#ifndef STR_OUT_H
#endif
#include <stdio.h>
#include "str_out.h"
void str_out( const char* str )
{
}
#include <stdio.h>
#include <dlfcn.h> //
#include <stdlib.h>
#include "str_out.h"
// 此例为动态加载动态库,Makefile中会提到静态如何关联加载
int main()
{
}
/ * Makefile */
tdynamicload : main.c str_out.so
注:选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中,
目的是能够通过使用 dlopen 来实现向后跟踪。
str_out.so : str_out.c str_out.h
注:由以上命令生成动态库str_out.so,为了可以静态加载动态库,
在这个命名方式中,第一个*表示动态链接库的库名,第二个*通常表示该动态库的版本号,
也可以没有版本号。
函数 描述
dlopen 使对象文件可被程序访问
dlsym
dlerror
dlclose 关闭目标文件
该过程首先是调用 dlopen,提供要访问的文件对象和模式。调用 dlopen 的结果是稍候要使用的对象的句柄。mode 参数通知动态链接器何时执行再定位。有两个可能的值。第一个是 RTLD_NOW,它表明动态链接器将会在调用 dlopen 时完成所有必要的再定位。第二个可选的模式是 RTLD_LAZY,它只在需要时执行再定位。这是通过在内部使用动态链接器重定向所有尚未再定位的请求来完成的。这样,动态链接器就能够在请求时知晓何时发生了新的引用,而且再定位可以正常进行。后面的调用无需重复再定位过程。
还可以选择另外两种模式,它们可以按位 OR 到 mode 参数中。RTLD_LOCAL 表明其他任何对象都无法使加载的共享对象的符号用于再定位过程。如果这正是您想要的的话(例如,为了让共享的对象能够调用原始进程映像中的符号),那就使用 RTLD_GLOBAL 吧。
dlopen 函数还会自动解析共享库中的依赖项。这样,如果您打开了一个依赖于其他共享库的对象,它就会自动加载它们。函数返回一个句柄,该句柄用于后续的 API 调用。dlopen 的原型为:#include <dlfcn.h>
void *dlopen( const char *file, int mode );
有了 ELF 对象的句柄,就可以通过调用 dlsym 来识别这个对象内的符号的地址了。该函数采用一个符号名称,如对象内的一个函数的名称。返回值为对象符号的解析地址:void *dlsym( void *restrict handle, const char *restrict name );
如果调用该 API 时发生了错误,可以使用 dlerror 函数返回一个表示此错误的人类可读的字符串。该函数没有参数,它会在发生前面的错误时返回一个字符串,在没有错误发生时返回 NULL:char *dlerror();
最后,如果无需再调用共享对象的话,应用程序可以调用 dlclose 来通知操作系统不再需要句柄和对象引用了。它完全是按引用来计数的,所以同一个共享对象的多个用户相互间不会发生冲突(只要还有一个用户在使用它,它就会待在内存中)。任何通过已关闭的对象的 dlsym 解析的符号都将不再可用。char *dlclose( void *handle );
Linux 动态库动态加载实例
最新推荐文章于 2024-06-13 17:39:18 发布