使用dlopen()访问.so库会抛出未定义的符号错误

时间:2013-01-31 10:45:01

标签: linux shared-libraries

我正在尝试将相机库.so文件动态加载到Linux可执行文件中以获取对简单相机功能的访问权限。

我试图通过以下方式做到这一点:

  if ( (newHandle = dlopen("./libCamera.so",RTLD_LAZY | RTLD_GLOBAL)) == NULL )
  {
     printf( "Could not open file : %s\n", dlerror() );   
     return 1;
  }

然而,这失败了,我收到以下输出:     “无法打开文件:libCamera.so:未定义的符号: ZTVN10 _cxxabiv117__class_type_infoE”

如何找出它所依赖的符号?

4 个答案:

答案 0 :(得分:14)

最有可能的是,libCamera.so使用共享库中定义的符号,而该库上没有依赖

  1. 找一个罪魁祸首。获取与libCamera.so链接的真实可执行文件(并且可以正常工作)。使用ldd /path/to/executable列出其依赖项。其中应该是一个具有ZTVN10_cxxabiv117__class_type_infoE定义的库(使用grep来选择可能的候选者,nm -D来确定库。{该库不会位于ldd ./libCamera.so所示的列表中。

  2. 解决问题。首先按dlopen加载步骤1中找到的库(同时使用RTLD_GLOBAL)。

  3. 如果其他符号出现问题,请转到第1步。

  4. 如果新添加的库也有同样的问题,请转到第1步。

  5. 告诉图书馆作者请修改他们的链接。

  6. 也可能发生ldd ./libCamera.so中的一个先决条件升级并丢失了一个符号定义(可能是使用编译器重新编译的,它的命名方式不同)。然后你不会在第1步中找到罪魁祸首,并且没有解决办法,只能再次降级某事

答案 1 :(得分:9)

ldd命令可用于显示共享库依赖项。

ldd libCamera.so

一旦了解了依赖关系,就可以使用nm来显示每个库中的符号。

nm -DC libCamera.so

答案 2 :(得分:5)

我有类似的问题。这与.a库有关,该库本应与我的.so相关联,并静态链接到遗漏的档案中。

我确定了这个(此处使用的OP对象名称):

nm mylibrary.so | grep ZTVN10_cxxabiv117__class_type_infoE
0000ABC0 U ZTVN10_cxxabiv117__class_type_infoE

U此处means that符号为"未定义"。您可以使用--demangle找到缺少的对象的已解码名称:

 $ nm --demangle mylibrary.so | grep 0000ABC0 
0000ABC0 U abi::class_type_info(params...)

(或类似的东西)这可以帮助你弄清楚缺少哪个库。

就我而言,即使在编译器行中包含库之后,我仍然遇到了问题。最后,在经过一些修改之后,我发现库文件(.a)必须在其依赖对象(.o)文件之后出现,如:

g++ -Wl,-E -g -m32 ... -fPIC myobjects1.o myobjects2.o missing_library.a -shared -o mylibrary.so

现在我得到了(不再是U):

 $ nm --demangle mylibrary.so | grep 0000ABC0 
0000ABC0 T abi::class_type_info(params...)

最重要的是我不再收到错误了!

答案 3 :(得分:1)

在libCamera.so的源代码中,您有未解析的外部符号。这意味着type_infoE在您的源代码中没有定义,应该解决。