免费注册 查看新帖 |

Chinaunix

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

[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;
}

最佳答案

查看完整内容

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

论坛徽章:
0
2 [报告]
发表于 2008-07-19 11:38 |只看该作者
GCC官方文档里讲
-llibrary
-l library
    Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)

    It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.


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

  1. g++ -shared  dll.cpp -L. -lA -o dll.so
复制代码

论坛徽章:
0
3 [报告]
发表于 2008-07-19 11:45 |只看该作者
Linux下的动态链接库我不懂,但有一点:

  1. extern "C"
  2. {
  3.     void maker(int id)
  4.     {
  5.         new dll<4>(id);
  6.     }
  7. }
复制代码

这里虽然指定了C链接方式,但编译器生成的符号名一般会带“_”前缀,在使用时使用“maker”就可以不正确了(我是按照Win下理解的,如果不对之处还望见谅)
在Win下有.def文件可解决此问题,如果确实是这个原因,在Linux下找找有没有对应的机制

论坛徽章:
0
4 [报告]
发表于 2008-07-19 11:48 |只看该作者
http://blog.csdn.net/Kendiv/archive/2008/03/29/2229406.aspx
Linux的version script与Windows的.DEF文件

你可以看看version script能否解决你的问题

论坛徽章:
0
5 [报告]
发表于 2008-07-19 12:24 |只看该作者
原帖由 tyc611 于 2008-7-19 11:45 发表


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


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

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

论坛徽章:
0
6 [报告]
发表于 2008-07-19 12:34 |只看该作者
没有必要指定extern C,你把它去掉重新编译一下看看.

论坛徽章:
0
7 [报告]
发表于 2008-07-19 12:45 |只看该作者

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

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


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

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

论坛徽章:
0
9 [报告]
发表于 2008-07-19 12:53 |只看该作者
手头没有linux开发环境,在win下面的gcc和make试了一下,应该是生成so文件的时候找不到A:A(int)函数的定义.

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

也就是说,生成so文件的时候使用的是obj文件,而不是静态库.
期待更好的解答.

论坛徽章:
0
10 [报告]
发表于 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当中呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP