免费注册 查看新帖 |

Chinaunix

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

[C++] 关于dlopen [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-19 11:38 |显示全部楼层 |倒序浏览
20可用积分
我的程序大体框架是这样的:

我把dll.cpp用-shared选项编译成dll.so,在dll.cpp当中引用了静态库libA.a当中的符号。然后dll.so是在main当中用dlopen打开的。

编译和链接都没有问题,但是在运行的时候会报如下的错误:

./dll.so: undefined symbol: _ZN1AC1EiSegmentation fault

所以我猜想可能是我在动态库中引用了静态库中的符号的缘故(参见Makefile中g++ -shared -L. -lA -o dll.so dll.cpp)。
请大家帮我看看怎么办呢? 应该加上什么参数呢?

各个文件文件的代码如下:

makefile
All:    main dll

main:    static dll main.cpp
    g++ -ldl -o main main.cpp

dll:    dll.cpp static
    g++ -shared -L. -lA -o dll.so dll.cpp

static:    A.cpp
    g++ -c A.cpp
    ar rc libA.a A.o


A.h
class A
{
public:
    A(int a);            
};

A.cpp
#include "A.h"
#include <iostream>

using namespace std;

A::A(int a)
{
    cout << "in A.A() " << a << endl;   
}

dll.cpp
#include <string>
#include <iostream>
#include "A.h"

using namespace std;

template<int F>
class dll
{
public:
    A *a;
public:
    dll(int id)
    {
        a = new A(id);
        cout << id << " " << F << endl;
    }
};

template class dll<4>;

extern "C"
{
    void maker(int id)
    {
        new dll<4>(id);
    }
}

main.cpp
#include <dlfcn.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    char *p;   
    void *lib;
    lib = dlopen("./dll.so", RTLD_LAZY);
    if (lib == NULL)
    {
        cout << "NULL" << endl;
        p = dlerror();
        cout << p << endl;
    }
    else
        cout << std::hex << lib << endl;
    typedef void (*FUNC) (int);
    FUNC sym = (FUNC) dlsym(lib, "maker");
    sym(3);


    return 0;
}

论坛徽章:
0
2 [报告]
发表于 2008-07-19 12:24 |显示全部楼层
原帖由 tyc611 于 2008-7-19 11:45 发表


这里虽然指定了C链接方式,但编译器生成的符号名一般会带“_”前缀,在使用时使用“maker”就可以不正确了(我是按照Win下理解的,如果不对之处还望见谅)


maker还是能够找到的,因为错误不是dlsym报的,而是dlopen报的。

我看看你给的网址吧,谢谢啦!

论坛徽章:
0
3 [报告]
发表于 2008-07-19 12:53 |显示全部楼层
原帖由 converse 于 2008-7-19 12:34 发表
没有必要指定extern C,你把它去掉重新编译一下看看.


还是不行。问题不在maker这里,因为在调用dlopen而不是dlsym的时候出错。

A的构造函数是在dll的构造函数中引用的,所以看样子在dlopen的时候好像dll的构造函数被调用了似的。

论坛徽章:
0
4 [报告]
发表于 2008-07-19 12:57 |显示全部楼层
原帖由 reiase 于 2008-7-19 12:45 发表

nm libA.a
看看那个符号是不是libA的吧


A.o:
         U __cxa_atexit
         U __dso_handle
000001d0 t _GLOBAL__I__ZN1AC2Ei
         U __gxx_personality_v0
000001bc t __tcf_0
0000017c t _Z41__static_initialization_and_destruction_0ii
00000140 T _ZN1AC1Ei
00000104 T _ZN1AC2Ei
         U _ZNKSs4sizeEv
         U _ZNKSsixEj
         U _ZNSolsEi
         U _ZNSolsEPFRSoS_E
         U _ZNSt8ios_base4InitC1Ev
         U _ZNSt8ios_base4InitD1Ev
00000000 t _ZSt17__verify_groupingPKcjRKSs
00000000 W _ZSt3minIjERKT_S2_S2_
         U _ZSt4cout
         U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b _ZSt8__ioinit
         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc


这里是nm libA.a的结果,看样子_ZN1AC1Ei有定义的样子…… 所以我猜是不是        g++ -shared -L. -lA -o dll.so dll.cpp 这句并没有有效地把libA.a链接到dll.so当中呢?

论坛徽章:
0
5 [报告]
发表于 2008-07-19 13:02 |显示全部楼层
原帖由 converse 于 2008-7-19 12:53 发表
手头没有linux开发环境,在win下面的gcc和make试了一下,应该是生成so文件的时候找不到A:A(int)函数的定义.

我将makfile改成这样就可以:
        g++ -shared -o dll.so dll.cpp A.o

也就是说,生成so文件的时候使 ...


恩,是的,我也觉得应该就是这句的问题,感觉在-shared生成动态库的时候指定的-lA并没有把相关的符号链接到dll.so当中去

论坛徽章:
0
6 [报告]
发表于 2008-07-19 13:04 |显示全部楼层
原帖由 reiase 于 2008-7-19 13:01 发表


这样的确可以,不过违背LZ的初衷了


恩,是的呀! 因为我要引用a库当中的很多类,不止这么一个,都用.o来链接太傻了呀。

不过还是要非常感谢各位仁兄! 期望更好的回答!

论坛徽章:
0
7 [报告]
发表于 2008-07-19 13:20 |显示全部楼层
原帖由 reiase 于 2008-7-19 13:17 发表
GCC官方文档里讲


是不是顺序问题
g++ -shared -L. -lA -o dll.so dll.cpp
在win下挂驴呢,LZ自己试试调整顺序吧

g++ -shared  dll.cpp -L. -lA -o dll.so


你说的很有道理,我试试看奥! 非常感谢!

论坛徽章:
0
8 [报告]
发表于 2008-07-19 13:23 |显示全部楼层
哭了,刚才那个解决了。 但为什么现在又报错说:

./dll.so: undefined symbol maker

呢?

论坛徽章:
0
9 [报告]
发表于 2008-07-19 13:26 |显示全部楼层
原帖由 tjsailor 于 2008-7-19 13:23 发表
哭了,刚才那个解决了。 但为什么现在又报错说:

./dll.so: undefined symbol maker

呢?

不好意思,一高兴忘记在makefile上加上dll.cpp了。
我现在搞定了,顺序是:

g++ -shared dll.cpp -o dll.so -L. -lA

论坛徽章:
0
10 [报告]
发表于 2008-07-19 13:48 |显示全部楼层
原帖由 reiase 于 2008-7-19 13:27 发表

先把dlopen的分给我,然后找converse问dlsym的问题


呵呵,真幽默。 评为最佳答案应该就把分已经给你了吧? 我不太会弄这个
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP