动态加载:共享静态库中未定义的符号
我有一个加载 .so
插件的可执行文件。
可执行文件与 -rdynamic
链接,以便可以发生符号回调。
我有一个包含在可执行文件中的静态库。 .a
中有一个名为 BLAH_hello()
的函数,
可执行文件中未使用静态库。即可执行代码中没有对 BLAH_hello()
的调用。
但是,.so
确实调用了 BLAH_hello()
。
当我 dlopen()
.so
时,它向 BLAH_hello()
抱怨未定义的符号
如果 我包含一个在可执行代码中对 BLAH_hello()
进行虚拟调用,例如 BLAH_hello(NULL);
。该符号包含在可执行文件中,当加载 .so
时,它会找到该符号。
我确信我也可以将 .so
链接到 .a
,但多个动态加载的 .so
使用 BLAH_hello
调用,因此将其包含在可执行文件中是有意义的。如果我将库链接到每个 .so
中,我还担心符号冲突。
所以我想知道的是,如何将 .a
的符号放入可执行文件中,即使它们实际上并未在可执行文件中使用?
I have an executable that loads .so
plugins.
The executable is linked with -rdynamic
so that symbol callback can occur.
I have a static library that is included in the executable. This has a function called BLAH_hello()
in the .a
The static library is not used in the executable. ie there are no calls to BLAH_hello()
in the executable code.
However, the .so
does have calls to BLAH_hello()
.
When I dlopen()
the .so
it complains about an undefined symbol to BLAH_hello()
If I include a dummy call to BLAH_hello()
in the executable code, like BLAH_hello(NULL);
. The symbol is included in the executable and when the .so
is loaded it finds the symbol.
I'm sure I could also link the .so
against the .a
but multiple dynamically loaded .so
's use the BLAH_hello
call so it makes sense to have it in the executable. I'm also worried about symbol conflict if I link the library into each .so
.
So what I'm wondering, is how to get the symbols of the .a
into the executable even if they aren't actually used in the executable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是完全正常且符合预期的。这只是链接器如何与存档库一起工作。
如果必须将
BLAH_hello
包含到主可执行文件中,请将-Wl,-u,BLAH_hello
添加到可执行链接行。That is completely normal and expected. It's just how linkers work with archive libraries.
If you must include
BLAH_hello
into the main executable, add-Wl,-u,BLAH_hello
to the executable link line.@nbt:
将
.so
加载到可执行文件时,这不应产生符号冲突。@nbt:
This should not generate symbol conflicts when loading the
.so
into an executable.如上所述,链接器会丢弃没有引用符号的 .o 文件。当可执行文件需要 dlopen() 外部共享库时,这是问题。在这种情况下,在链接可执行文件时,可以使用链接器选项“--whole-archive”和“--no-whole-archive”。这些选项之间的所有 .a 库都将包含所有符号。它增加了可执行文件的大小,但消除了链接到可执行文件的静态库的需要。
As mentioned above, the linker discards .o files with no referenced symbols. This is problem, when the executable needs to dlopen() external shared libs. In such case the linker options '--whole-archive' and '--no-whole-archive' can be used, when linking the executable. All .a libs between these options will have all symbols included. It increases the executable size, but removes the need to link to executable's static libs.