linux 加载so库

//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

 

你可能感兴趣的:(linux/unix,( ̄﹁ ̄))