在dlopen()函数以指定模式打开指定的动态链接库文件。并返回一个句柄给 dlsym()的调用进程。

使用 dlclose()来卸载打开的库。

功能:打开一个动态链接库,并返回动态链接库的句柄
包括头文件:
#include <dlfcn.h>
函数定义:
void * dlopen( const char * pathname, int mode);
函数描写叙述:
mode是打开方式,其值有多个,不同操作系统上实现的功能有所不同,在linux下,按功能可分为三类:
1、解析方式
RTLD_LAZY:在dlopen返回前,对于动态库中的没有定义的符号不运行解析(仅仅对函数引用有效。对于变量引用总是马上解析)。 RTLD_NOW: 须要在dlopen返回前。解析出全部没有定义符号,假设解析不出来。在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
2、作用范围,可与解析方式通过“|”组合使用。 RTLD_GLOBAL:动态库中定义的符号可被其后打开的其他库解析。
RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其他库重定位。 假设没有指明是RTLD_GLOBAL还是RTLD_LOCAL。则缺省为RTLD_LOCAL。
3、作用方式
RTLD_NODELETE: 在dlclose()期间不卸载库,而且在以后使用dlopen()又一次载入库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
RTLD_NOLOAD: 不载入库。 可用于測试库是否已载入(dlopen()返回NULL说明未载入,否则说明已载入),也可用于改变已载入库的flag,如:先前载入库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号。避免同名符号的冲突。这个flag不是POSIX-2001标准。
返回值:
打开错误返回NULL
成功,返回库引用
编译时候要增加 -ldl (指定dl库)
比如
gcc test.c -o test -ldl
#include <stdlib.h>
#include <dlfcn.h>
#include <stdio.h> //申明结构体
typedef struct __test {
int i;
void (* echo_fun)(struct __test *p);
}Test; //供动态库使用的注冊函数
void __register(Test *p) {
p->i = 1;
p->echo_fun(p);
} int main(void) { void *handle = NULL;
char *myso = "./mylib.so"; if((handle = dlopen(myso, RTLD_NOW)) == NULL) {
printf("dlopen - %sn", dlerror());
exit(-1);
} return 0;
}
#include <stdio.h>
#include <stdlib.h> //申明结构体类型
typedef struct __test {
int i;
void (*echo_fun)(struct __test *p);
}Test; //申明注冊函数原型
void __register(Test *p); static void __printf(Test *p) {
printf("i = %dn", p->i);
} //动态库申请一个全局变量空间
//这样的 ".成员"的赋值方式为c99标准
static Test config = {
.i = 0,
.echo_fun = __printf,
}; //载入动态库的自己主动初始化函数
void _init(void) {
printf("initn");
//调用主程序的注冊函数
__register(&config);
}

主程序编译: gcc test.c -ldl -rdynamic

动态库编译: gcc -shared -fPIC -nostartfiles -o mylib.so mylib.c

主程序通过dlopen()载入一个.so的动态库文件, 然后动态库会自己主动执行 _init() 初始化函数, 初始化函数打印一个提示信息, 然后调用主程序的注冊函数给结构体又一次赋值, 然后调用结构体的函数指针, 打印该结构体的值. 这样就充分的达到了主程序和动态库的函数相互调用和指针的相互传递.

gcc參数 -rdynamic 用来通知链接器将全部符号加入到动态符号表中(目的是可以通过使用 dlopen
来实现向后跟踪).

gcc參数 -fPIC 作用: 当使用.so等类的库时,当遇到多个可运行文件共用这一个库时, 在内存中,这个库就不会被复制多份,让每一个可运行文件一对一的使用,而是让多个可运行文件指向一个库文件,达到共用. 宗旨:节省了内存空间,提高了空间利用率.

<pre name="code" class="cpp">dlsym函数:
函数原型是
void* dlsym(void* handle,const char* symbol)
该函数在<dlfcn.h>文件里。 handle是由dlopen打开动态链接库后返回的指针。symbol就是要求获取的函数的名称,函数 返回值是void*,指向函数的地址,供调用使用。

导入库函数使用方法:
 

#include <dlfcn.h>

void* handle = dlopen("./hello.so", RTLD_LAZY);

typedef void (*hello_t)();

hello_t hello = (hello_t) dlsym(handle, "hello");



hello();

dlclose(handle);

注意库函数在库中的定义要用extern“c”来申明,这样在主函数中才干通过“hello”来查找函数。申明的方式有下面两种:

extern "C" int foo;

extern "C" void bar();

            

and 



extern "C" {

     extern int foo;

     extern void bar();

}

导入类库方法:

#include "polygon.hpp" //类定义处



#include <dlfcn.h>



void* triangle = dlopen("./triangle.so", RTLD_LAZY);

create_t* create_triangle = (create_t*) dlsym(triangle, "create");



destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");

polygon* poly = create_triangle();

// use the class



    poly->set_side_length(7);

    cout << "The area is: " << poly->area() << '\n';

// destroy the class



    destroy_triangle(poly);



    // unload the triangle library



    dlclose(triangle);



dlopen 方式调用 Linux 的动态链接库的更多相关文章

  1. .netcore在linux下使用P/invoke方式调用linux动态库

    http://www.mamicode.com/info-detail-2358309.html   .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...

  2. linux中动态链接库的创建与使用

    LINUX系统中动态链接库的创建与使用 http://www.cnblogs.com/ardar/articles/357321.html 正常C源文件编写,编译时-shared即可得到SO, gcc ...

  3. Linux 关于动态链接库以及静态链接库的一些概念

    库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀.例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhe ...

  4. linux下动态链接库解决方案(二)

    以前写过一个关于linux下用c++写动态链接库无法通过的解决方案,今天看到<linux C程序设计-王者归来>这本书,书中有个更容易的解决方案,特此记录下来 书中使用的是c语言,我改用c ...

  5. Python调用C/C++动态链接库

    Python调用C/C++动态链接库 2013年07月26日 ⁄ 综合 ⁄ 共 3219字 ⁄ 字号 小 中 大 ⁄ 评论关闭   吐槽(可略过):不知不觉,4月份毕业,5月份进入团队,已有7个月.大 ...

  6. 【转】Python调用C语言动态链接库

    转自:https://www.cnblogs.com/fariver/p/6573112.html 动态链接库在Windows中为.dll文件,在linux中为.so文件.以linux平台为例说明py ...

  7. 如何在java程序中调用linux命令或者shell脚本

    转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...

  8. Python调用C/C++动态链接库的方法详解

    Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...

  9. 文本分类学习 (十)构造机器学习Libsvm 的C# wrapper(调用c/c++动态链接库)

    前言: 对于SVM的了解,看前辈写的博客加上读论文对于SVM的皮毛知识总算有点了解,比如线性分类器,和求凸二次规划中用到的高等数学知识.然而SVM最核心的地方应该在于核函数和求关于α函数的极值的方法: ...

随机推荐

  1. BZOJ5017 炸弹(线段树优化建图+Tarjan+拓扑)

    Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...

  2. maven+spring-data-jpa环境搭建

    转自http://www.cnblogs.com/007sx/p/5658194.html 首先看一下项目结构: 所用到的jar(pom.xml): <project xmlns="h ...

  3. python web开发 框架 模板 MVC

    我是跟着廖雪峰老师学习的,对于我这样的纯小白来说,跟着他的网站学习,简直是被妈妈抱在怀里一样无忧无虑,这样的学习本来没有记录下来的必要,但是由于我的粗心大意,经常会出现一些错误,所以我决定把这些错误记 ...

  4. Mysql 锁表 for update (引擎/事务)

    因为之前用过oracle,知道利用select * for update 可以锁表.所以很自然就想到在mysql中能不能适应for update来锁表呢. 学习参考如下 由于InnoDB预设是Row- ...

  5. java无依赖读取Excel文件

    说到Java读取Excel文件,用得多的当然是POI或jxls,但今天在看一本书的时候.当中提到使用JdbcOdbcDriver这个驱动类在不依赖第三方库的情况下也能够完毕对Excel文件的读取操作, ...

  6. void指针 (补充)

    void* 表示空指针.空指针不能直接使用,比如,指针的加减法操作(由于不知道类型,无法确定偏移的大小).某些情况下.不知道指针的类型,先用void*来取代,依据须要再强制转换成须要的指针类型使用. ...

  7. HDU 2435 There is a war Dinic 最小割

    题意是有n座城市,n号城市不想让1号城市可达n号,每条道路有一条毁坏的代价,1号还可以修一条不能毁坏的道路,求n号城市所需的最小代价最大是多少. 毁坏的最小代价就直接求一遍最大流,就是最小割了.而可以 ...

  8. PHP高手进阶-LAMPer技能树

  9. angularCli打包遇到的一些问题

    有时在运行项目或者打包项目的时候会遇到报错信息:found version 4, expected 3, 这个大概意思是说该插件需要的依赖当前不支持,需要提高依赖的版本. 比如:@angular/co ...

  10. 重装python 和 yum

    https://blog.csdn.net/ghostyusheng/article/details/https://segmentfault.com/q/1010000009194060/a-102 ...