简体   繁体   English

未找到来自共享库的符号,但已定义

[英]Symbol from shared library not found, though defined

I'm working on C++ code called, via pybind11, from a Python (v3.8) application on Ubuntu 20.04.我正在处理通过 pybind11 从 Ubuntu 20.04 上的 Python (v3.8) 应用程序调用的 C++ 代码。

Running the application I get an error运行应用程序我得到一个错误

Traceback (most recent call last):
snip...
ImportError: <full-path>/<lib-name-A>.so: undefined symbol: <mangled symbol name>

ldd on lib-name-A output gives the absolute path to lib B in which the symbol is defined. ldd on lib-name-A output 给出了定义符号的 lib B 的绝对路径。 nm -s --demangle on lib B shows the symbol is defined in the text section. nm -s --demangle on lib B 显示符号在文本部分中定义。 Just to be sure, I compared the mangled name, and the one in lib B is identical to the one given in the error message.可以肯定的是,我比较了损坏的名称,lib B 中的名称与错误消息中给出的名称相同。

So, given the library exists where ldd shows its expected, and the symbol is defined in it, why do I get the error message?因此,假设库存在于 ldd 显示其预期位置的位置,并且其中定义了符号,为什么我会收到错误消息?

nm -s --demangle` on lib B shows the symbol is defined in the text section lib B 上的 nm -s --demangle` 显示符号在文本部分中定义

The function being defined in lib B is necessary, but not sufficient. lib B 中定义的 function 是必需的,但还不够。 The function must also be exported from lib B. function 也必须从 lib B导出

Chances are, it's not.有可能,事实并非如此。 To verify, run:要验证,请运行:

nm -D /path/to/lib-B.so | grep $mangled_symbol_name_here

If my guess is correct (function is not exported), you will get no output from above command.如果我的猜测是正确的(函数未导出),您将不会从上面的命令中得到 output。

Update:更新:

Checking with nm -D , and the symbol is missing.使用nm -D检查,符号丢失。 Checking again with -s , the symbol has t (lowercase) next to it, rather than T再次检查-s ,符号旁边有t (小写),而不是T

Ok, so my guess was correct.好的,所以我的猜测是正确的。

I've added __attribute__((visibility("default"))) in front of the function declaration,我在 function 声明前添加了__attribute__((visibility("default")))

That's the correct solution.这才是正确的解决方案。

Question is why I need to declare it explicitly as visible.问题是为什么我需要明确声明它是可见的。

Most likely because you are building this code with -fvisibility=hidden , which says "hide everything not explicitly declared as visible".很可能是因为您正在使用-fvisibility=hidden构建此代码,它表示“隐藏所有未明确声明为可见的内容”。

Building with -fvisibility=hidden is current best practice, but you do need to mind which symbols are used outside of the shared library you are building.使用-fvisibility=hidden进行构建是当前的最佳实践,但您确实需要注意在您正在构建的共享库之外使用了哪些符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM