12

我正在尝试将相机库 .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

4 回答 4

17

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

  1. 找到罪魁祸首。获取一个链接的真正可执行文件libCamera.so(并且它可以工作)。用 列出其依赖项ldd /path/to/executable。其中应该是一个库,它有一个定义ZTVN10_cxxabiv117__class_type_infoE(用于grep选择可能的候选者,nm -D肯定是在一个库上)。该库不会出现在 显示的列表中ldd ./libCamera.so

  2. 解决问题。首先加载在步骤 1 中找到的库dlopen(也在那里使用RTLD_GLOBAL)。

  3. 如果另一个符号有问题,请转到步骤 1。

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

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

也可能发生ldd ./libCamera.so升级的先决条件之一并丢失符号定义(也许它是用一个名称不同的编译器重新编译的)。那么你就不会在步骤 1 中找到罪魁祸首了,没有解决办法,只能再次降级。

于 2013-01-31T10:52:38.110 回答
10

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

ldd libCamera.so

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

nm -DC libCamera.so
于 2013-01-31T10:48:49.010 回答
6

我有一个类似的问题。这与一个.a图书馆有关,它应该链接到我的.so并静态链接到被遗漏的档案中。

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

nm mylibrary.so | grep ZTVN10_cxxabiv117__class_type_infoE
0000ABC0 U ZTVN10_cxxabiv117__class_type_infoE

这里的U意思符号是“未定义的”。您可以使用以下命令找到丢失对象的解构名称--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...)

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

于 2015-05-01T08:23:50.690 回答
1

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

于 2013-06-22T09:36:34.860 回答