使用dlopen加载动态库时访问主程序全局变量报错,如何解决?
动态库加载失败:extern引用主程序全局变量的问题解决
你的问题核心是动态库加载时无法解析主程序中的全局符号a,默认情况下主程序的全局符号不会导出到动态符号表,导致动态库找不到extern声明的a,进而触发dlopen报错。
问题代码回顾
Main.c:
#include <dlfcn.h> #include <stdio.h> int a = 37; int main(){ void *lib = dlopen("./libA.so", RTLD_NOW); if(dlerror() != NULL){ printf("Error loading library.\n"); return -1; } void (*f)() = dlsym(lib, "fun"); // 补充:调用函数验证功能 if(f) f(); dlclose(lib); return 0; }
Lib.c:
#include <stdio.h> extern int a; void fun(){ printf("%i\n", a); }
解决步骤
- 编译动态库:保留
-fPIC和-shared参数,生成位置无关的动态库文件
gcc -fPIC -shared Lib.c -o libA.so
- 编译主程序时添加
-rdynamic参数:该参数会强制链接器将主程序的全局符号导出到动态符号表,让动态库能解析依赖的符号
gcc Main.c -o main -ldl -rdynamic
- 运行程序:
./main
此时程序会正常输出37,dlopen不再抛出加载错误。
原理说明
你使用的RTLD_NOW模式要求dlopen时立即解析所有未定义符号,但主程序默认不会将全局符号对外暴露,动态库找不到a就会加载失败。-rdynamic参数会让主程序的全局符号加入动态符号表,动态库就能通过符号查找定位到主程序中的a变量。
内容的提问来源于stack exchange,提问作者MorsaHelada
相关产品推荐
相关产品推荐

