在 C++ 中,可以从动态库中访问外部定义的全局变量吗?
我在头文件中声明了一个全局变量,如下所示;
文件名:TestVariable.hpp
#ifndef TESTVARIABLE_HPP
#define TESTVARIABLE_HPP
extern
int testVariable;
#endif
然后在源代码文件中定义如下;
文件名:TestVariable.cpp
int testVariable;
构成我的动态库的源代码如下;
文件名:插件.cpp
#include <TestVariable.hpp>
#ifdef __cplusplus
extern "C" {
#endif
void *
__attribute__((constructor))
loadLibrary
(
void
)
{
testVariable = 100;
}
void *
__attribute__((destructor))
unloadLibrary
(
void
)
{
}
#ifdef __cplusplus
}
#endif
然后我的主要功能定义如下;
文件名:main.cpp
#include <iostream>
#include <dlfcn.h>
// dlopen
#include <TestVariable.hpp>
using std::cout;
using std::endl;
int main(void)
{
void * libHandle_p = NULL;
cout << "Test variable = " << testVariable << endl;
// Load the dynamic library.
libHandle_p = dlopen("./.libs/libPlugin.so", RTLD_LAZY);
if (libHandle_p == NULL)
{
cout << "Error loading library" << endl;
return(-1);
}
cout << "Test variable = " << testVariable << endl;
return(0);
}
我可以使用 GNU Autotools、g++ 和 ld 正确编译和链接所有代码(并且没有任何警告),但是当我运行生成的二进制可执行文件时,它无法 dlopen 动态库文件。但是,如果我注释掉包含函数loadLibrary主体的唯一一行代码,然后重新编译和链接,则程序可以正常工作!
如果我不知道更好,我会说当 dlopen 调用它(库)时,库无法解析其对全局变量testVariable的引用,这就是导致 dlopen 操作失败的原因。链接类型和/或名称修饰可能与此问题有关吗?
如果我在生成的动态库上运行 Linux nm 实用程序,它会通知我符号testVariable未定义,即“U”。如果我在二进制可执行文件上运行 nm 实用程序,它会通知我符号testVariable存在并驻留在未初始化的数据部分中,即“B”。那么为什么dlopen在加载动态库的时候不能解析这个符号呢?
我只从源文件Plugin.cpp生成动态库。二进制可执行文件是从 2 个源代码文件main.cpp和TestVariable.cpp 生成的。
有人可以帮忙吗。我可以发誓答案是盯着我的脸,但我只是没有看到它。
提前致谢。