免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2031 | 回复: 2
打印 上一主题 下一主题

前段时间碰到的加载多个共享库的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-27 17:32 |只看该作者 |倒序浏览
问题描述:加载两个或两个以上的共享库(以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)
{
&nbsp;&nbsp;&nbsp;&nbsp;void *dl1, *dl2, *dl3;
&nbsp;&nbsp;&nbsp;&nbsp;func_t f1, f2, f3;

&nbsp;&nbsp;&nbsp;&nbsp;dl1 = dlopen("./libmodule1.so", RTLD_GLOBAL | RTLD_NOW);
&nbsp;&nbsp;&nbsp;&nbsp;f1 = (func_t)dlsym(dl1, "get_string");

&nbsp;&nbsp;&nbsp;&nbsp;dl2 = dlopen("./libmodule2.so", RTLD_GLOBAL | RTLD_NOW);
&nbsp;&nbsp;&nbsp;&nbsp;f2 = (func_t)dlsym(dl2, "get_string");

&nbsp;&nbsp;&nbsp;&nbsp;dl3 = dlopen("./libmodule3.so", RTLD_GLOBAL | RTLD_NOW);
&nbsp;&nbsp;&nbsp;&nbsp;f3 = (func_t)dlsym(dl3, "get_string");

&nbsp;&nbsp;&nbsp;&nbsp;cout << f1() << endl;
&nbsp;&nbsp;&nbsp;&nbsp;cout << f2() << endl;
&nbsp;&nbsp;&nbsp;&nbsp;cout << f3() << endl;

&nbsp;&nbsp;&nbsp;&nbsp;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

只有第三个共享库的输出不正确,被第二个加载的共享库的覆盖掉了。

论坛徽章:
0
2 [报告]
发表于 2007-12-27 17:37 |只看该作者
写这个验证程序只是想验证一下这个猜测,最好的方法还是去查看加载共享库的代码

论坛徽章:
0
3 [报告]
发表于 2007-12-28 10:42 |只看该作者
去掉RTLD_GLOBAL
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP