处理共享对象中的全局变量
Handling global variables in shared object
我在 global.c 文件中定义了一些全局变量,如下所示:
int globalvar;
我有一个头文件 global.h 将这个变量声明为 extern
extern int globalVar;
现在我有 main.c 与已编译的 global.o(从 global.c 编译)链接,具有打开(使用 dlopen)共享对象 sh.so 的代码从 sh.c 构建,通过 global.h 访问 globalVar。
尽管我的可执行文件具有 globalVar 的定义(静态链接),但当我加载动态链接库 sh.so 时,它显示未定义的 globalVar。
如何处理?
更多的是解释而不是解决方案(我不是 Linux 共享库的专家),在 global.o
和 sh.so
中只有变量和函数的地址他们自己的单位是已知的。
因此,要让共享库知道全局变量在您的可执行文件中的位置,您必须告诉动态库在哪里可以找到它,即它的地址是什么。同理,当你想调用动态库中的函数时,你必须请求库的地址。
Antti Haapala How can a shared library (.so) call a function that is implemented in its loader program? 的 link 展示了如何执行此操作。
Although, my executable has definition of globalVar (statically linked), when I load the dynamically linked library sh.so, it says undefined globalVar.
这是意料之中的。一个 ELF 二进制文件有 两个 符号 tables:一个是常规的,一个是用于动态 linking 的。您可以像这样检查它们:
nm a.out | grep globalVar # expected: address D globalVar
nm -D a.out | grep globalVar # expected: no output
linker 没有将 globalVar
放入动态符号 table 的原因是(在 link 时间)二进制文件之外的任何东西都不需要该符号.
How to handle this?
有几种方法。
- 如果您将
-rdynamic
添加到 link 行,您将要求 linker 将 每个 定义的符号导出到动态符号 table。虽然总的来说这是个坏主意,但这是解决您问题的最快方法。
- 如果您使用金币 link,您可以使用
-Wl,--export-dynamic-symbol=globalVar
仅导出 globalVar
- 您可以使用
-Wl,--dynamic-list=globals.txt
并将 globalVar
放入 globals.txt
文件。
- 您可以使用
-Wl,--dynamic-list-data
导出所有全局数据变量(这只比-rdynamic
稍微好一点)。
我在 global.c 文件中定义了一些全局变量,如下所示:
int globalvar;
我有一个头文件 global.h 将这个变量声明为 extern
extern int globalVar;
现在我有 main.c 与已编译的 global.o(从 global.c 编译)链接,具有打开(使用 dlopen)共享对象 sh.so 的代码从 sh.c 构建,通过 global.h 访问 globalVar。 尽管我的可执行文件具有 globalVar 的定义(静态链接),但当我加载动态链接库 sh.so 时,它显示未定义的 globalVar。 如何处理?
更多的是解释而不是解决方案(我不是 Linux 共享库的专家),在 global.o
和 sh.so
中只有变量和函数的地址他们自己的单位是已知的。
因此,要让共享库知道全局变量在您的可执行文件中的位置,您必须告诉动态库在哪里可以找到它,即它的地址是什么。同理,当你想调用动态库中的函数时,你必须请求库的地址。
Antti Haapala How can a shared library (.so) call a function that is implemented in its loader program? 的 link 展示了如何执行此操作。
Although, my executable has definition of globalVar (statically linked), when I load the dynamically linked library sh.so, it says undefined globalVar.
这是意料之中的。一个 ELF 二进制文件有 两个 符号 tables:一个是常规的,一个是用于动态 linking 的。您可以像这样检查它们:
nm a.out | grep globalVar # expected: address D globalVar
nm -D a.out | grep globalVar # expected: no output
linker 没有将 globalVar
放入动态符号 table 的原因是(在 link 时间)二进制文件之外的任何东西都不需要该符号.
How to handle this?
有几种方法。
- 如果您将
-rdynamic
添加到 link 行,您将要求 linker 将 每个 定义的符号导出到动态符号 table。虽然总的来说这是个坏主意,但这是解决您问题的最快方法。 - 如果您使用金币 link,您可以使用
-Wl,--export-dynamic-symbol=globalVar
仅导出globalVar
- 您可以使用
-Wl,--dynamic-list=globals.txt
并将globalVar
放入globals.txt
文件。 - 您可以使用
-Wl,--dynamic-list-data
导出所有全局数据变量(这只比-rdynamic
稍微好一点)。