- 论坛徽章:
- 0
|
问题描述:加载两个或两个以上的共享库(以RTLD_GLOBAL标记调用dlopen),并且这些共享库包含有同名的全局变量,则后面加载的共享库只能引用到第一个共享库的同名全局变量。
下面的这些代码是用来测试这个问题的。分别生成三个共享库libmodule1.so,libmodule2.so,libmodule3.so,以及一个主程序文件test。三个共享库都有名为buf的全局数组,主程序的功能就是想把这三个模块的全局数组中的字符串输出。但是在这里,程序只能够输出三行“module 1”,后面加载的两个共享库都引用到了第一个共享库的buf了。
// module1.cpp
extern "C" {
char buf[] = "module 1";
char * get_string(void)
{
return buf;
}
} |
// module2.cpp
extern "C" {
char buf[] = "module 2";
char * get_string(void)
{
return buf;
}
} |
// module3.cpp
extern "C" {
char buf[] = "module 3";
char * get_string(void)
{
return buf;
}
} |
#include <iostream>
#include <dlfcn.h>
using namespace std;
typedef char * (*func_t)(void);
int main(int argc, char ** argv)
{
void *dl1, *dl2, *dl3;
func_t f1, f2, f3;
dl1 = dlopen("./libmodule1.so", RTLD_GLOBAL | RTLD_NOW);
f1 = (func_t)dlsym(dl1, "get_string");
dl2 = dlopen("./libmodule2.so", RTLD_GLOBAL | RTLD_NOW);
f2 = (func_t)dlsym(dl2, "get_string");
dl3 = dlopen("./libmodule3.so", RTLD_GLOBAL | RTLD_NOW);
f3 = (func_t)dlsym(dl3, "get_string");
cout << f1() << endl;
cout << f2() << endl;
cout << f3() << endl;
return 0;
} |
附Makefile文件
all: libmodule1.so libmodule2.so libmodule3.so test
libmodule1.so: module1.cpp
g++ -shared -g0 -O0 -o libmodule1.so module1.cpp
libmodule2.so: module2.cpp
g++ -shared -g0 -O0 -o libmodule2.so module2.cpp
libmodule3.so: module3.cpp
g++ -shared -g0 -O0 -o libmodule3.so module3.cpp
test: main.cpp
g++ -g0 -O0 -o test -ldl main.cpp
clean:
rm -f *.so test
|
要是加载第一个共享库的dlopen的flag参数中不包含RTLD_GLOBAL标志:
dl1 = dlopen("./libmodule1.so", RTLD_NOW); |
那么程序的输出就变成了
module 1
module 2
module 2
只有第三个共享库的输出不正确,被第二个加载的共享库的覆盖掉了。 |
|