我正在尝试将相机库.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”
如何找出它所依赖的符号?
答案 0 :(得分:14)
最有可能的是,libCamera.so
使用共享库中定义的符号,而该库上没有依赖。
找一个罪魁祸首。获取与libCamera.so
链接的真实可执行文件(并且可以正常工作)。使用ldd /path/to/executable
列出其依赖项。其中应该是一个具有ZTVN10_cxxabiv117__class_type_infoE
定义的库(使用grep
来选择可能的候选者,nm -D
来确定库。{该库不会位于ldd ./libCamera.so
所示的列表中。
解决问题。首先按dlopen
加载步骤1中找到的库(同时使用RTLD_GLOBAL
)。
如果其他符号出现问题,请转到第1步。
如果新添加的库也有同样的问题,请转到第1步。
告诉图书馆作者请修改他们的链接。
也可能发生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
在您的源代码中没有定义,应该解决。