调用dlopen()时共享库构造函数未执行的技术问题
dlopen加载共享库时构造函数没执行?这么解决
几个可能的原因和修复办法
1. dlopen的调用参数不对
调用dlopen()的时候,如果只用默认的RTLD_LAZY,有时会因为符号延迟解析,导致构造函数没触发。改成显式传RTLD_NOW | RTLD_GLOBAL试试:
void *handle = dlopen("./module_A.so", RTLD_NOW | RTLD_GLOBAL);
RTLD_NOW会立刻解析所有符号,保证构造函数能执行;RTLD_GLOBAL让库的符号对后续加载的库可见,避免符号找不到的问题。
2. printf输出被缓冲,没显示出来
你代码里的printf没加换行符\n,而且没手动刷新缓冲,导致输出被卡在缓冲区里,看起来像是没执行。要么给字符串加上\n,要么在printf之后加fflush(stdout)强制刷新:
__attribute__((constructor)) int init_module() { printf("Module init\n"); // 加换行符触发缓冲自动刷新 // 也可以手动加这行强制刷新:fflush(stdout); return 0; }
3. 构造函数的签名不规范
虽然GCC允许带返回值的构造函数,但标准的构造函数应该是无参数、无返回值的,改成这样更稳妥:
__attribute__((constructor)) void init_module() { printf("Module init\n"); fflush(stdout); } __attribute__((destructor)) void deinit_module() { printf("Module deinit\n"); fflush(stdout); }
避免因为签名问题被编译器忽略。
4. 编译时丢了必要的选项
有些环境下,GCC默认的链接器选项会把没被直接引用的构造函数符号优化掉,编译的时候加上-Wl,--no-as-needed:
gcc -shared -fPIC -Wl,--no-as-needed -o module_A.so module.c
防止构造函数被意外丢弃。
验证步骤
- 按上面的方法改代码,补换行符或者加fflush
- 用修改后的编译命令重新生成.so文件
- 调用dlopen时传对参数
- 再看是不是能输出"Module init"了
内容的提问来源于stack exchange,提问作者Martijn Courteaux
相关产品推荐
相关产品推荐

