欢迎来到天天文库
浏览记录
ID:8802172
大小:20.58 KB
页数:6页
时间:2018-04-08
《dlopen及so动态加载原理》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、Linux提供了一套API来动态装载库。下面列出了这些API:-dlopen,打开一个库,并为使用该库做些准备。-dlsym,在打开的库中查找符号的值。-dlclose,关闭库。-dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。C语言用户需要包含头文件dlfcn.h才能使用上述API。glibc还增加了两个POSIX标准中没有的API:-dladdr,从函数指针解析符号名称和所在的文件。-dlvsym,与dlsym类似,只是多了一个版本字符串参数。在Linux上,使用动态链接的应用程序需要和库li
2、bdl.so一起链接,也就是使用选项-ldl。但是,编译时不需要和动态装载的库一起链接。程序3-1是一个在Linux上使用dl*例程的简单示例。延迟重定位(LazyRelocation)延迟重定位/装载是一个允许符号只在需要时才重定位的特性。这常在各UNIX系统上解析函数调用时用到。当一个和共享库一起链接的应用程序几乎不会用到该共享库中的函数时,该特性被证明是非常有用的。这种情况下,只有库中的函数被应用程序调用时,共享库才会被装载,否则不会装载,因此会节约一些系统资源。但是如果把环境变量LD_BIND_NOW设置成一个非空值,所有的重定位操作都会在程
3、序启动时进行。也可以在链接器命令行通过使用-znow链接器选项使延迟绑定对某个特定的共享库失效。需要注意的是,除非重新链接该共享库,否则对该共享库的这种设置会一直有效。初始化(initializing)和终止化(finalizing)函数有时候,以前的代码可能用到了两个特殊的函数:_init和_fini。_init和_fini函数用在装载和卸载某个模块(注释14)时分别控制该模块的构造器和析构器(或构造函数和析构函数)。他们的C语言原型如下:void_init(void);void_fini(void);当一个库通过dlopen()动态打开或以共享库
4、的形式打开时,如果_init在该库中存在且被输出出来,则_init函数会被调用。如果一个库通过dlclose()动态关闭或因为没有应用程序引用其符号而被卸载时,_fini函数会在库卸载前被调用。当使用你自己的_init和_fini函数时,需要注意不要与系统启动文件一起链接。可以使用GCC选项-nostartfiles做到这一点。但是,使用上面的函数或GCC的-nostartfiles选项并不是很好的习惯,因为这可能会产生一些意外的结果。相反,库应该使用__attribute__((constructor))和__attribute__((destru
5、ctor))函数属性来输出它的构造函数和析构函数。如下所示:void__attribute__((constructor))x_init(void)void__attribute__((destructor))x_fini(void)构造函数会在dlopen()返回前或库被装载时调用。析构函数会在这样几种情况下被调用:dlclose()返回前,或main()返回后,或装载库过程中exit()被调用时。我们通过一个例子来讲解dlopen系列函数的使用和操作:主程序:1.#include 2.#include 3.#
6、include 4.5.//申明结构体6.typedefstruct__test {7. int i;8. void (* echo_fun)(struct__test *p);9.}Test;10.11.//供动态库使用的注册函数12.void__register(Test *p) {13. p->i = 1;14. p->echo_fun(p);15.}16.17.int main(void) {18.19. void *handle = NULL;20. char *myso = "./my
7、lib.so";21.22. if((handle = dlopen(myso, RTLD_NOW)) == NULL) {23. printf("dlopen-%sn", dlerror());24. exit(-1);25. }26.27. return0;28.}动态库:1.#include 1.#include 2.3.//申明结构体类型4.typedefstruct__test {5. int i;6. void (*echo_fun)(stru
8、ct__test *p);7.}Test;8.9.//申明注册函数原型10.void__register(T
此文档下载收益归作者所有