为什么这个动态加载的库不能访问加载程序的全局变量?

发布于 2024-10-08 02:22:42 字数 1031 浏览 8 评论 0原文

首先,我看到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

宣告ˉ结束 2024-10-15 02:22:44

您已创建了两个 global_var 实例。其中一个是在 liba.so 中定义的,并且是 bc 引用的那个。

另一个在 a 中定义,这是您的 main() 函数所引用的那个。

如果您希望主函数引用 liba.so 中的变量,则需要对其进行 extern 声明而不是定义,并且需要链接到该库本身。

You've created two instances of global_var. One is defined in liba.so, and that's the one that b.c is referencing.

The other is defined in a, and that's the one that your main() function is referencing.

If you want your main function to reference the variable in liba.so, it needs an extern declaration of it instead of a definition, and it needs to link against that library itself.

司马昭之心 2024-10-15 02:22:44

有趣的问题。
答案也很有趣。

正如 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

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.

# cat imp.imp
 #!.

 global_var

cc main.c -bexpall
cc  lib.c -bM:SRE -bnoentry -bI:./imp.imp -bexpall -o libb.so
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文