问题描述
当我导入我构建的模块时,我得到这个与boost-python相关的错误:
When I import a module I built, I get this boost-python related error:
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?
推荐答案
描述
问题是混合使用 libc ++
编译的对象和使用 libstdc ++编译的对象
。
在我们的例子中,库 myMod.so
(使用 <$编译) c $ c> libstdc ++ )需要使用 libstdc ++ $编译的
( boost-python
c $ c> boost-python-libstdc ++
从现在开始)。当 boost-python
是 boost-python-libstdc ++
时,它会正常工作。否则 - 在计算机上,其 boost-python
已使用 libc ++
(或其他c ++)编译库),加载和运行它会有问题。
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.
在我们的例子中,它发生是因为 libc ++
开发人员故意改名称所有符号都阻止你(并保存你)混合来自他们库的代码和来自不同代码的代码: myMod.so
需要一个从类型。在 libc ++
中,此类型的名称为 std :: __ 1 :: pair
。因此,找不到此符号。
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.
要理解为什么混合两个版本的相同API是坏的,请考虑以下情况:有两个库: Foo
和 Bar
。它们都有一个函数,它接受 std :: string
并将它用于某些东西,但它们使用不同的c ++库。当 Foo
创建的 std :: string
将传递给 Bar ,
Bar
会认为这是其c ++库的 std :: string
的一个实例,然后会发生不好的事情(它们是完全不同的对象)。
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的更多不同版本。如果他们将在它们之间传递此API的对象,则会出现问题。但是,检查可能非常困难,特别是如果它们仅将API对象作为另一个对象的成员传递。此外,库的初始化函数可以执行不应发生两次的事情。另一个版本可能会再次执行这些操作。
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.
-
您始终可以重新编译库并使它们相互匹配。
You can always recompile your libraries and make them match each other.
您可以将 boost-python
链接到您的库作为静态库。然后,它几乎可以在每台计算机上运行(即使是没有安装 boost-python
的计算机)。查看更多相关信息。
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 has boost-python
installed). See more about that here.
myMod.so
需要另一个版本的 boost-python
,一个用特定的c ++库编译的版本。因此,它不适用于任何其他版本。
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.
这篇关于什么是“符号未找到/期望:平面命名空间”实际上是什的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!