如果我的进程没有定义变量但它被用作共享库中的外部变量,会发生什么?

What will happen if my process not defined a variable but it is used as a extern variable in a shared library?

我有 2 个进程 A 和 B。两个进程共享同一个名为 common_add.so

的共享对象文件

我在进程A中定义了变量g_test_variable

但是如果我没有在进程 B 中定义变量 g_test_variable 并使用 dlopen & dlsym 打开 common_add.so 文件并调用未使用 [=19= 的 add_double 函数] 变量,我会遇到任何问题吗?

/*
 * File Name : common.c
 * This file packaged as part of common_add.so
 */
extern int_32 g_test_variable; //declaration
int add_int(int a, int b)
{
   if(g_test_variable)
      printf("somthing");

      return a+b;
}

double add_double(double a, double b)
{
      return a-b;
}

(我说的是Linux系统)

所以你有一个程序aa(进程A中的运行)和一个程序bb(进程B中的运行)。两者都使用 common_add.so

但是如果aa没有定义符号g_test_variable(在common_add.so的某些全局ELF symbol table) its dynamic linking中会失败。

如何以及何时发生可能取决于动态 linking 是如何完成的。

如果您正在使用 dlopen(3),您最好传递 RTLD_NOW 以避免懒惰 linking。然后 dlopen 会失败,而 dlerror 会给出有用的信息。

如果您将默认值 RTLD_LAZY 传递给 dlopen,则错误可能仅在第一次调用 add_int 或什至显然不相关的 [=19= 时触发](但细节可能因实施而异)

(不要忘记为 common_add.so 插件编译 common.c-fPIC,link 主要 aabb 节目 -rdynamic)

另见 this and read Drepper's How To Write Shared Libraries 论文。

我建议使用 RTLD_NOW 在早期 dlopen 时间捕获此类错误。当然,如果引用了未定义的符号,您不能指望程序能够运行! (所以你应该要求主程序定义 g_test_variable ...)。您可以考虑在插件中将 g_test_variable 声明为 weak symbol(但我通常不推荐此类技巧)。