dlopen 方式调用 Linux 的动态链接库
在dlopen()函数以指定模式打开指定的动态链接库文件。并返回一个句柄给 dlsym()的调用进程。
功能:打开一个动态链接库,并返回动态链接库的句柄
包括头文件:
#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*,指向函数的地址,供调用使用。
|
|
注意库函数在库中的定义要用extern“c”来申明,这样在主函数中才干通过“hello”来查找函数。申明的方式有下面两种:
|
|
导入类库方法:
|
|
dlopen 方式调用 Linux 的动态链接库的更多相关文章
- .netcore在linux下使用P/invoke方式调用linux动态库
http://www.mamicode.com/info-detail-2358309.html .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...
- linux中动态链接库的创建与使用
LINUX系统中动态链接库的创建与使用 http://www.cnblogs.com/ardar/articles/357321.html 正常C源文件编写,编译时-shared即可得到SO, gcc ...
- Linux 关于动态链接库以及静态链接库的一些概念
库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀.例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhe ...
- linux下动态链接库解决方案(二)
以前写过一个关于linux下用c++写动态链接库无法通过的解决方案,今天看到<linux C程序设计-王者归来>这本书,书中有个更容易的解决方案,特此记录下来 书中使用的是c语言,我改用c ...
- Python调用C/C++动态链接库
Python调用C/C++动态链接库 2013年07月26日 ⁄ 综合 ⁄ 共 3219字 ⁄ 字号 小 中 大 ⁄ 评论关闭 吐槽(可略过):不知不觉,4月份毕业,5月份进入团队,已有7个月.大 ...
- 【转】Python调用C语言动态链接库
转自:https://www.cnblogs.com/fariver/p/6573112.html 动态链接库在Windows中为.dll文件,在linux中为.so文件.以linux平台为例说明py ...
- 如何在java程序中调用linux命令或者shell脚本
转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...
- Python调用C/C++动态链接库的方法详解
Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...
- 文本分类学习 (十)构造机器学习Libsvm 的C# wrapper(调用c/c++动态链接库)
前言: 对于SVM的了解,看前辈写的博客加上读论文对于SVM的皮毛知识总算有点了解,比如线性分类器,和求凸二次规划中用到的高等数学知识.然而SVM最核心的地方应该在于核函数和求关于α函数的极值的方法: ...
随机推荐
- P3514 [POI2011]LIZ-Lollipop(规律+瞎搞)
题意 给一个只有1和2的序列,每次询问有没有一个子串的和为x ( 1≤n,m≤1 000 000 )kkk ( 1≤k≤2 000 000 ) 题解 我觉得是道好题. 主要是证明一个性质:假如有一个字 ...
- [NOIP2014提高组]寻找道路
题目:洛谷P2296.Vijos P1909.codevs3731.UOJ#19. 题目大意:给你一张有向图,边权为1,让你找一条s到t的最短路径,但这条路径上所有点的出边所指向的点都与终点连通.如果 ...
- 解决MAC下PHP连接MYSQL错误Warning: mysql_connect(): No such file or directory in conn.php
今天在mac上用php去连接mysql数据库,出现了 mac PHP Warning: mysql_connect(): [2002] No such file... 详细例如以下所看到的: Dir ...
- Oracle EBS发放销售订单
模拟发放销售订单界面进行发放操作 PROCEDURE insert_row(x_batch_id OUT NUMBER) IS l_autopack_flag VARCHAR2(1 ); l_a ...
- js斐波那契数列求和
一.递归算法 function recurFib(n) { if (n < 2) { return n; } else { return recurFib(n-1) ...
- Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)
题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...
- 5. webservice通信调用天气预报接口实例
转自:https://blog.csdn.net/xiejuan6105/article/details/78452605 一:环境搭建 1:新建一个java project工程weatherInf ...
- 1.cocos_helloworld
在class HelloWorld : public cocos2d::Layer中添加函数 void menuclose(cocos2d::Ref *psender); 实现: void Hello ...
- P1824 进击的奶牛
题目描述 Farmer John建造了一个有N(2<=N<=100,000)个隔间的牛棚,这些隔间分布在一条直线上,坐标是x1,...,xN (0<=xi<=1,000,000 ...
- Android中Gallery和ImageSwitcher同步自动(滚动)播放图片库
本文主要内容是如何让Gallery和ImageSwitcher控件能够同步自动播放图片集 ,看起来较难,然而,实现的方法非常简单, 请跟我慢慢来.总的来说,本文要实现的效果如下图:(截图效果不怎么好) ...