Linux 使用 dlopen() 访问 .so 库会引发未定义的符号错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14623873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing .so libraries using dlopen() throws undefined symbol error
提问by Joey Big
I'm trying to dynamically load a camera library .so file into a Linux executable to gain access to simple camera functions.
我正在尝试将相机库 .so 文件动态加载到 Linux 可执行文件中,以访问简单的相机功能。
I'm attempting to do this by:
我试图通过以下方式做到这一点:
if ( (newHandle = dlopen("./libCamera.so",RTLD_LAZY | RTLD_GLOBAL)) == NULL )
{
printf( "Could not open file : %s\n", dlerror() );
return 1;
}
However this fails and I receive the following output: "Could not open file : libCamera.so: undefined symbol: ZTVN10_cxxabiv117__class_type_infoE"
但是这失败了,我收到以下输出:“无法打开文件:libCamera.so:未定义符号:ZTVN10_cxxabiv117__class_type_infoE”
How do I find out what symbols it is relying on?
我如何找出它所依赖的符号?
采纳答案by Anton Kovalenko
Most likely, libCamera.so
uses a symbol defined in a shared library without dependingon that library.
最有可能libCamera.so
使用共享库中定义的符号,而不依赖于该库。
Find a culprit. Take a real executable which links against
libCamera.so
(and it works). List its dependencies withldd /path/to/executable
. Among them should be a library which has a definition forZTVN10_cxxabiv117__class_type_infoE
(usegrep
to select likely candidates,nm -D
on a library to be sure). That library won'tbe in the list shown byldd ./libCamera.so
.Solve a problem. Load the library found in step 1 by
dlopen
first (useRTLD_GLOBAL
there as well).If there is a problem with another symbol, goto step 1.
If newly-added libraries have the same problem too, goto step 1.
Tell library authors to please fix their linking.
找出罪魁祸首。拿一个真正的可执行文件链接
libCamera.so
(并且它可以工作)。用 列出它的依赖项ldd /path/to/executable
。其中应该有一个图书馆,它有一个定义ZTVN10_cxxabiv117__class_type_infoE
(用于grep
选择可能的候选人,nm -D
在图书馆上确定)。该库不会在 显示的列表中ldd ./libCamera.so
。解决问题。首先加载在步骤 1 中找到的库
dlopen
(RTLD_GLOBAL
也在那里使用)。如果另一个符号有问题,请转到步骤 1。
如果新添加的库也有同样的问题,请转到步骤1。
告诉图书馆作者请修复他们的链接。
It could also happen that one of the prerequisites in ldd ./libCamera.so
got upgraded and lost a symbol definition (maybe it was recompiled with a compiler which does name mangling differently). Then you won't find the culprit in step 1, and there is no solution but downgrading somethingagain.
也可能发生ldd ./libCamera.so
升级并丢失符号定义的先决条件之一(也许它是用不同名称修改的编译器重新编译的)。然后,你不会找到在步骤1中的罪魁祸首,并没有解决办法,但降级的东西一次。
回答by Austin Phillips
The ldd
command can be used to display shared library dependencies.
该ldd
命令可用于显示共享库依赖项。
ldd libCamera.so
Once you know the dependencies, you can use nm
to show the symbols in each library.
一旦知道了依赖关系,就可以使用nm
来显示每个库中的符号。
nm -DC libCamera.so
回答by A23149577
In your source code for libCamera.so, you have unresolved external symbol. It means that type_infoE
have no definition in your source code and should be resolved.
在 libCamera.so 的源代码中,您有未解析的外部符号。这意味着type_infoE
在您的源代码中没有定义,应该解决。
回答by robert
I had a similar problem. It was to do with a .a
library, which should have been linked to my .so
and statically linked into the archive being left out.
我有一个类似的问题。这与一个.a
图书馆有关,它应该链接到我的,.so
并静态链接到被遗漏的档案中。
I determined this with (OP object name used here):
我用(此处使用的 OP 对象名称)确定了这一点:
nm mylibrary.so | grep ZTVN10_cxxabiv117__class_type_infoE
0000ABC0 U ZTVN10_cxxabiv117__class_type_infoE
The U
here means thatthe symbol is "undefined". You can find the demangled name of the missing object with --demangle
:
在U
这里指的符号是“不确定”。您可以使用以下命令找到丢失对象的损坏名称--demangle
:
$ nm --demangle mylibrary.so | grep 0000ABC0
0000ABC0 U abi::class_type_info(params...)
(or something like that) this should help you figure out which library is missing.
(或类似的东西)这应该可以帮助您找出缺少哪个库。
In my case, even after including the library on the compiler line I still had the issue. Eventually, after some tinkering I discovered that the library-file (.a
) has to come after its dependent object (.o
) file like:
就我而言,即使在编译器行中包含库后,我仍然遇到问题。最终,经过一些修补后,我发现库文件 ( .a
) 必须在其依赖对象 ( .o
) 文件之后,例如:
g++ -Wl,-E -g -m32 ... -fPIC myobjects1.o myobjects2.o missing_library.a -shared -o mylibrary.so
Now I get (no more U
):
现在我得到(不再U
):
$ nm --demangle mylibrary.so | grep 0000ABC0
0000ABC0 T abi::class_type_info(params...)
and most importantly I don't get the error any more!
最重要的是,我再也不会收到错误消息了!