本文介绍了“Symbol not found/Expected in: flat namespace"是什么意思?其实是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我导入一个我构建的模块时,我得到这个与 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++ 编译的对象混合引起的.

Description

The problem was caused by mixing objects that compiled with libc++ and object that compiled with libstdc++.

在我们的例子中,库 myMod.so(用 libstdc++ 编译)需要 boost-python使用 libstdc++(从现在开始boost-python-libstdc++)编译.当 boost-pythonboost-python-libstdc++ 时,它会正常工作.否则 - 在它的 boost-pythonlibc++(或其他 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 的两个版本是不好的,请考虑这种情况:有两个库:FooBar.他们都有一个接受 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.

这篇关于“Symbol not found/Expected in: flat namespace"是什么意思?其实是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 19:16