//RTLD_LAZY:在dlopen返回前,对于动态库中的没有定义的符号不运行解析(仅仅对函数引用有效。对于变量引用总是马上解析)。
//RTLD_NOW: 须要在dlopen返回前。解析出全部没有定义符号,假设解析不出来。在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
//RTLD_GLOBAL:动态库中定义的符号可被其后打开的其他库解析。
//RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其他库重定
void *handle = dlopen(filename, RTLD_LOCAL | RTLD_LAZY);
const char *version = (const char *)dlsym(handle, "version");
void (*module_init)()= (void(*)())dlsym(handle, "module_init");
if(!module_init)
{
fprintf(stderr, "%s MediaServiceInit >>%s\n", name, dlerror());
dlclose(handle);
}
module_init();
函数导出:
__attribute__ ((visibility ("default")))
__attribute__ ((visibility ("hidden")))
库查看(符号作用域):
#读取elf文件
readelf -s libtest.so
43: 00000000000006c6 19 FUNC LOCAL DEFAULT 12 test1
61: 00000000000006b3 19 FUNC GLOBAL DEFAULT 12 test
#查看符号表
objdump -t libtest.so
00000000000006c6 l F .text 0000000000000013 test1
00000000000006b3 g F .text 0000000000000013 test
#查看动态符号表(只显示g d D DF),g代表GLOBAL(global)导出的符号,可以被查找并调用
objdump -T
00000000000006b3 g DF .text 0000000000000013 Base test
#使用nm查看T(导出的)和t (没导出)
nm libtest.so
00000000000006b3 T test
00000000000006c6 t test1
ar 用于打包成静态文件.a
编译:
主程序编译需要:
-Wl,--export-dynamic -fvisibility=hidden
SO库编译
gcc -fvisibility=hidden -fPIC -shared libtest.c -o libtest.so