Python “Symbol not found / Expected in: flat namespace”究竟是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35006614/
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
What does "Symbol not found / Expected in: flat namespace" actually mean?
提问by kilojoules
When I import a module I built, I get this boost-python related error:
当我导入我构建的模块时,我收到了与 boost-python 相关的错误:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(./myMod.so, 2): Symbol not found: __ZN5boost6python7objects15function_objectERKNS1_11py_functionERKSt4pairIPKNS0_6detail7keywordES9_E
Referenced from: ./myMod.so
Expected in: flat namespace
in ./myMod.so
What does this actually mean? Why was this error raised?
这实际上意味着什么?为什么会出现这个错误?
采纳答案by Shmuel H.
Description
描述
The problem was caused by mixing objects that compiled with libc++
and object that compiled with libstdc++
.
该问题是由混合使用编译的libc++
对象和使用编译的对象引起的libstdc++
。
In our case, the library myMod.so
(compiled with libstdc++
) need boost-python
that compiled with libstdc++
(boost-python-libstdc++
from now). When boost-python
is boost-python-libstdc++
, it will work fine. Otherwise - on computer that its boost-python
has compiled with libc++
(or another c++ library), it will have a problem loading and running it.
在我们的例子中,库myMod.so
(用 编译libstdc++
)需要boost-python
用libstdc++
(boost-python-libstdc++
从现在开始)编译。如果boost-python
是boost-python-libstdc++
,它会正常工作。否则 - 在其boost-python
编译的计算机libc++
(或其他 C++ 库)上,加载和运行它会出现问题。
In our case, it happens because that libc++
developers intentionally changed the name of all of their symbols to prevent you (and save you) from mixing code from their library and code from a different one: myMod.so
need a function that take an argument from the type. In libc++
, this type's name is std::__1::pair
. Therefore, this symbol was not found.
在我们的例子中,发生这种情况是因为libc++
开发人员有意更改了所有符号的名称,以防止您(并保存您)将来自他们库的代码与来自不同库的代码混合:myMod.so
需要一个从类型中获取参数的函数。在 中libc++
,这种类型的名称是std::__1::pair
。因此,没有找到这个符号。
To understand why mixing two version of the same API is bad, consider this situation: There are two libraries: Foo
and Bar
. They both have a function that takes a std::string
and uses it for something but they use a different c++ library. When a std::string
that has been created by Foo
will be passed to Bar
, Bar
will think that this is an instance of its c++ library's std::string
and then bad things can happen (they are a completely different objects).
要了解为什么混合使用同一 API 的两个版本是不好的,请考虑这种情况:有两个库:Foo
和Bar
. 他们都有一个接受 a 的函数,并将std::string
其用于某事,但他们使用不同的 C++ 库。当 astd::string
创建的Foo
will 传递给 时Bar
,Bar
会认为这是其 C++ 库的实例,std::string
然后可能会发生不好的事情(它们是完全不同的对象)。
Note: In some cases, there would be no problem with two or more different versions of the same API in a completely different parts of a program. There will be a problem if they will pass this API's objects between them. However, checking that can be very hard, especially if they pass the API object only as a member of another object. Also, a library's initialization function can do things that should not happen twice. Another version may do these things again.
注意:在某些情况下,同一 API 的两个或多个不同版本在程序的完全不同的部分中是没有问题的。如果它们在它们之间传递这个 API 的对象,就会出现问题。但是,检查可能非常困难,尤其是当他们仅将 API 对象作为另一个对象的成员传递时。此外,库的初始化函数可以做不应发生两次的事情。另一个版本可能会再次做这些事情。
How to solve that?
如何解决?
You can always recompile your libraries and make them match each other.
You can link
boost-python
to your library as a static library. Then, it will work on almost every computer (even one that doesn't hasboost-python
installed). See more about that here.
您可以随时重新编译您的库并使它们相互匹配。
您可以链接
boost-python
到您的库作为静态库。然后,它几乎可以在每台计算机上运行(即使是没有boost-python
安装的计算机)。在此处查看更多相关信息。
Summary
概括
myMod.so
need another version of boost-python
, one that compiled with a specific c++ library. Therefore, It would not work with any another version.
myMod.so
需要另一个版本的boost-python
,一个使用特定 C++ 库编译的版本。因此,它不适用于任何其他版本。
回答by kilojoules
Here's what I've learned (osx):
这是我学到的东西(osx):
If this is supposed to work (i.e. it works on another computer), you may be experiencing clang/gcc issues. To debug this, use otool -l
on the .so file which is raising the error, or a suspect library (in my example it's a boost-python dylib file) and examine the contents. Anything in the /System/ folder is built with clang, and should be installed somewhere else with the gcc compiler. Never delete anything in the /System folder.
如果这应该可以工作(即它可以在另一台计算机上工作),则您可能遇到了 clang/gcc 问题。要对此进行调试,请使用otool -l
引发错误的 .so 文件或可疑库(在我的示例中它是一个 boost-python dylib 文件)并检查内容。/System/ 文件夹中的任何内容都是使用 clang 构建的,并且应该使用 gcc 编译器安装在其他地方。切勿删除 /System 文件夹中的任何内容。
回答by zvone
.so
files are dynamic libraries (so = shared object). On Windows they are called .dll
(dynamic-link library). They contain compiled code which contains functions available for usage to any executable which links them.
.so
文件是动态库(so = 共享对象)。在 Windows 上,它们被称为.dll
(动态链接库)。它们包含已编译的代码,其中包含可用于链接它们的任何可执行文件的函数。
What is important to notice here is that those .so
are not Python files. They were probably compiled from C or C++ code and contain public functions which can be used from Python code (see documentation on Extending Python with C or C++).
这里需要注意的重要一点是那些.so
不是 Python 文件。它们可能是从 C 或 C++ 代码编译的,并且包含可以从 Python 代码中使用的公共函数(请参阅有关使用 C 或 C++ 扩展 Python 的文档)。
On your case, well, you have a corrupt .so
. Try reinstalling the affected libraries, or Python, or both.
在你的情况下,你有一个腐败的.so
. 尝试重新安装受影响的库或 Python,或两者。
回答by Misgevolution
Symbol not found means the definition of the declared function or variable was not found. When a header file of a shared object is compiled with your program, linker adds symbols of declared functions and objects to your compiled program. When your program is loaded by the OS's loader, the symbols are resolved so that their definition will be loaded. It is only at this time where if the implementation is missing, loader complains it couldn't find the definition due to may be failing to resolve the actual path to the library or the library itself wasn't compiled with the implementation/source file where the definition of the function or object resides. There is a good article on this on the linux journal http://www.linuxjournal.com/article/6463.
未找到符号表示未找到声明的函数或变量的定义。当共享对象的头文件与您的程序一起编译时,链接器会将声明的函数和对象的符号添加到您编译的程序中。当您的程序由操作系统的加载器加载时,符号将被解析,以便加载它们的定义。只是此时如果缺少实现,加载器会抱怨它找不到定义,因为可能无法解析到库的实际路径,或者库本身没有与实现/源文件一起编译,其中函数或对象的定义驻留。在 linux 期刊http://www.linuxjournal.com/article/6463上有一篇关于此的好文章。
回答by zhaofeng-shu33
I encounter the same problem.
我遇到了同样的问题。
Expected in: flat namespace
Add the linker flag fixes the problem
添加链接器标志修复了问题
-lboost_python37
change the dynamic library name to the one installed on the os.
将动态库名称更改为安装在操作系统上的名称。
By the way, my os is macOS High Sierra and I use brew to install boost_python3
.
顺便说一下,我的操作系统是 macOS High Sierra,我使用 brew 安装boost_python3
.
回答by Rexcirus
In my case I was just failing to import all the required sources (c++ files) when compiling with Cython.
在我的情况下,我只是在使用 Cython 编译时未能导入所有必需的源(c++ 文件)。
From the string after "Symbol not found" you can understand which library you are missing.
从“找不到符号”之后的字符串中,您可以了解您缺少哪个库。