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

Joe*_*Big 11 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;
  }
Run Code Online (Sandbox Code Playgroud)

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

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

Ant*_*nko 15

最有可能的是,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中的罪魁祸首,并没有解决办法,但降级的东西一次.


Aus*_*ips 10

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

ldd libCamera.so
Run Code Online (Sandbox Code Playgroud)

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

nm -DC libCamera.so
Run Code Online (Sandbox Code Playgroud)


rob*_*ert 5

我有一个类似的问题。这与一个.a库有关,该库应该已链接到我的库,并已.so静态链接到被忽略的存档中。

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

nm mylibrary.so | grep ZTVN10_cxxabiv117__class_type_infoE
0000ABC0 U ZTVN10_cxxabiv117__class_type_infoE
Run Code Online (Sandbox Code Playgroud)

U这里的符号是“不确定”。您可以使用以下命令找到缺少的对象的拆散名称--demangle

 $ nm --demangle mylibrary.so | grep 0000ABC0 
0000ABC0 U abi::class_type_info(params...)
Run Code Online (Sandbox Code Playgroud)

(或类似的东西),这应该可以帮助您确定缺少哪个库。

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

g++ -Wl,-E -g -m32 ... -fPIC myobjects1.o myobjects2.o missing_library.a -shared -o mylibrary.so
Run Code Online (Sandbox Code Playgroud)

现在我得到了(没有更多U):

 $ nm --demangle mylibrary.so | grep 0000ABC0 
0000ABC0 T abi::class_type_info(params...)
Run Code Online (Sandbox Code Playgroud)

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