dlopen及so动态加载原理

上传人:nu****n 文档编号:102953935 上传时间:2022-06-07 格式:DOCX 页数:6 大小:12.76KB
收藏 版权申诉 举报 下载
dlopen及so动态加载原理_第1页
第1页 / 共6页
dlopen及so动态加载原理_第2页
第2页 / 共6页
dlopen及so动态加载原理_第3页
第3页 / 共6页
资源描述:

《dlopen及so动态加载原理》由会员分享,可在线阅读,更多相关《dlopen及so动态加载原理(6页珍藏版)》请在装配图网上搜索。

1、Linux提供了一套API来动态装载库。下面列出了这些API:- dlopen,打开一个库,并为使用该库做些准备。- dlsym,在打开的库中查找符号的值。- dlclose,关闭库。- dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。C语言用户需要包含头文件dlfcn.h才能使用上述API。glibc还增加了两个POSIX标准中没有的API:- dladdr,从函数指针解析符号名称和所在的文件。- dlvsym,与dlsym类似,只是多了一个版本字符串参数。在Linux上,使用动态链接的应用程序需要和库libdl.so一起链接,也就是使用

2、选项-ldl。但是,编译时不需要和动态装载的库一起链接。程序3-1是一个在Linux上使用dl*例程的简单示例。延迟重定位(Lazy Relocation)延迟重定位/装载是一个允许符号只在需要时才重定位的特性。这常在各UNIX系统上解析函数调用时用到。当一个和共享库一起链接的应用程序几乎不会用到该共享库中的函数时,该特性被证明是非常有用的。这种情况下,只有库中的函数被应用程序调用时,共享库才会被装载,否则不会装载,因此会节约一些系统资源。但是如果把环境变量LD_BIND_NOW设置成一个非空值,所有的重定位操作都会在程序启动时进行。也可以在链接器命令行通过使用-z now链接器选项使延迟绑定

3、对某个特定的共享库失效。需要注意的是,除非重新链接该共享库,否则对该共享库的这种设置会一直有效。初始化(initializing)和终止化(finalizing)函数有时候,以前的代码可能用到了两个特殊的函数:_init和_fini。_init和_fini函数用在装载和卸载某个模块(注释14)时分别控制该模块的构造器和析构器(或构造函数和析构函数)。他们的C语言原型如下:void _init(void);void _fini(void);当一个库通过dlopen()动态打开或以共享库的形式打开时,如果_init在该库中存在且被输出出来,则_init函数会被调用。如果一个库通过dlclose()

4、动态关闭或因为没有应用程序引用其符号而被卸载时,_fini函数会在库卸载前被调用。当使用你自己的_init和_fini函数时,需要注意不要与系统启动文件一起链接。可以使用GCC选项 -nostartfiles 做到这一点。但是,使用上面的函数或GCC的-nostartfiles选项并不是很好的习惯,因为这可能会产生一些意外的结果。相反,库应该使用_attribute_(constructor)和_attribute_(destructor)函数属性来输出它的构造函数和析构函数。如下所示:void _attribute_(constructor) x_init(void)void _attrib

5、ute_(destructor) x_fini(void)构造函数会在dlopen()返回前或库被装载时调用。析构函数会在这样几种情况下被调用:dlclose()返回前,或main()返回后,或装载库过程中exit()被调用时。我们通过一个例子来讲解dlopen系列函数的使用和操作:主程序:1. #include2. #include3. #include4.5. /申明结构体6. typedef struct _test7. inti;8. void(*echo_fun)(struct _test*p);9. Test;10.11. /供动态库使用的注册函数12. void _registe

6、r(Test*p)13. p-i=1;14. p-echo_fun(p);15. 16.17. intmain(void)18.19. void*handle=NULL;20. char*myso=./mylib.so;21.22. if(handle=dlopen(myso,RTLD_NOW)=NULL)23. printf(dlopen - %sn,dlerror();24. exit(-1);25. 26.27. return 0;28. 动态库:1. #include2. #include3.4. /申明结构体类型5. typedef struct _test6. inti;7. vo

7、id(*echo_fun)(struct _test*p);8. Test;9.10. /申明注册函数原型11. void _register(Test*p);12.13. static void _printf(Test*p)14. printf(i = %dn,p-i);15. 16.17. /动态库申请一个全局变量空间18. /这种.成员的赋值方式为c99标准19. static Test config=20. .i=0,21. .echo_fun=_printf,22. ;23.24. /加载动态库的自动初始化函数25. void _init(void)26. printf(initn

8、);27. /调用主程序的注册函数28. _register(&config);29. 主程序编译:gcc test.c -ldl -rdynamic动态库编译:gcc -shared -fPIC -nostartfiles -o mylib.so mylib.c主程序通过dlopen()加载一个.so的动态库文件, 然后动态库会自动运行 _init() 初始化函数, 初始化函数打印一个提示信息, 然后调用主程序的注册函数给结构体重新赋值, 然后调用结构体的函数指针, 打印该结构体的值. 这样就充分的达到了主程序和动态库的函数相互调用和指针的相互传递.gcc参数-rdynamic 用来通知链接

9、器将所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪).gcc参数 -fPIC 作用: 当使用.so等类的库时,当遇到多个可执行文件共用这一个库时, 在内存中,这个库就不会被复制多份,让每个可执行文件一对一的使用,而是让多个可执行文件指向一个库文件,达到共用. 宗旨:节省了内存空间,提高了空间利用率.linux生成(加载)动态库静态库和加载示例方法动态库的生成:1、/*mysum.c*/#include #include src.hint sum(int a,int b)return (a+b);2、/*mysum.h*/代码如下:#ifndef _SRC_H_#d

10、efine _SRC_H_int sum(int a,int b);#endif3、/*main.c*/代码如下:#include extern int sum(int a,int b);/*#include #include mysum.h*/int main()int a,b,c=0;printf(input a and b:n);scanf(%d %d,&a,&b);c = sum(a,b);printf(c = %dn,c);return 0;4、生成动态库代码如下:gcc -c -fPIC mysum.c mysum.h /生成mysum.o文件gcc -shared -fPIC -

11、o libmysum.so mysum.o /生成动态库文件,默认的命名方式为lib+名称.so5、动态库静态加载代码如下:gcc -o main main.c -L. -lmysum -Wall或gcc -o main main.c -lmysum -Wall6、执行 ./main时会报告错误,提示无法加载libmysum.so共享库。7、处理方法有三:方法一:将动态库拷贝到 /lib或 /usr/lib中去如:sudo cp libmysum.so /lib方法二:改变环境变量:LD_LIBRARY_PATH=$PWD export LD_LIBRARY_PATH方法三:在编译时指定共享库的路径:gcc -o main1 -Wl,-rpath,.-L. -louyang main.o

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!