为什么这个动态加载的库不能访问加载程序的全局变量?
首先,我看到 this(<- 链接),但它不起作用。我使用的是 OS X。
ac:
#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;
}
bc:
#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
?我尝试了许多编译器标志的组合,但没有一个起作用。
First of all, I have seen this (<- a link), and it isn't working. I am using OS X.
a.c:
#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);
}
Compiling and running:
$ 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
Why doesn't it print 0x9263
? I have tried many combinations of compiler flags, and none of them work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您已创建了两个
global_var
实例。其中一个是在liba.so
中定义的,并且是bc
引用的那个。另一个在
a
中定义,这是您的main()
函数所引用的那个。如果您希望主函数引用 liba.so 中的变量,则需要对其进行
extern
声明而不是定义,并且需要链接到该库本身。You've created two instances of
global_var
. One is defined inliba.so
, and that's the one thatb.c
is referencing.The other is defined in
a
, and that's the one that yourmain()
function is referencing.If you want your main function to reference the variable in
liba.so
, it needs anextern
declaration of it instead of a definition, and it needs to link against that library itself.有趣的问题。
答案也很有趣。
正如 caf 在他的回复中提到的,您创建了 global_var 的两个定义。
要实现您想要实现的目标,您必须确保从主可执行文件解析 global_var 。为此,您必须创建一个导入文件,其中声明 global_var 是从主可执行文件导入的。在导入文件中,您应该使用#!。为了这。
然后在创建库时使用此导入文件。
另外,在编译主二进制文件时,请确保导出 global_var 变量。使用适当的编译器标志。
在我的 unix 机器上,我尝试了这个并且它有效。
Interesting question.
The answer is also interesting.
As caf mentioned in his reply, you have created two definitions of global_var.
To do what you are trying to achieve, you have to make sure that, global_var is resolved from main executable. for that , you will have to create an import file which states that, global_var is imported from main executable. In the import file, you should use #!. for this.
Then use this import file while creating the library.
Also while compiling the main binary, make sure that the global_var variable is exported. use appropriate compiler flags.
On my unix box, i tried this and it works.