为什么这个动态加载的库不能访问加载程序的全局变量?
问题描述:
首先,我看到了this(< - 一个链接),它不起作用。我使用的OS X.为什么这个动态加载的库不能访问加载程序的全局变量?
交流转换器:
#include <stdio.h>
#include <dlfcn.h>
int global_var = 0x9262;
int main(void) {
void *handle = dlopen("libb.so", RTLD_LAZY);
void (*func)(void);
char *err;
if (handle == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
func = dlsym(handle, "func");
if ((err = dlerror()) != NULL) {
fprintf(stderr, "%s\n", err);
return 2;
}
global_var = 0x9263;
func();
return -dlclose(handle) * 3;
}
b.c:
#include <stdio.h>
extern int global_var;
void func(void) {
printf("0x%x\n", global_var);
}
编译和运行:
$ gcc -shared -rdynamic -fpic -o liba.so a.c
$ gcc -shared -fpic -o libb.so -L. -la b.c
$ gcc -fpic -o a a.c
$ ./a
0x9262
为什么它不打印0x9263
?我已经尝试了许多编译器标志的组合,并且它们都不起作用。
答
您已创建global_var
的两个实例。其中一个在liba.so
中定义,这就是b.c
所引用的那个。
另一种是在a
中定义的,这就是你的main()
函数引用的那个。
如果你想要你的主函数引用liba.so
中的变量,它需要一个extern
声明它而不是一个定义,它需要链接到该库本身。
答
有趣的问题。 答案也很有趣。
正如他在回复中提到的caf,你已经创建了两个global_var的定义。
要做你正在努力实现的,你必须确保global_var从主可执行文件中解析出来。为此,您将不得不创建一个导入文件,其中声明global_var是从主可执行文件导入的。在导入文件中,您应该使用#!.为了这。
然后在创建库时使用此导入文件。
同时在编译主二进制文件时,确保导出global_var变量。使用适当的编译器标志
在我的unix盒子上,我试过这个,它工作。
# cat imp.imp
#!.
global_var
cc main.c -bexpall
cc lib.c -bM:SRE -bnoentry -bI:./imp.imp -bexpall -o libb.so
+0
#未能在帖子中正确显示 – cexpert 2010-12-20 06:55:18
+1正确(还有一些字符) – slezica 2010-12-20 04:58:22