且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

“符号未找到/预期在:平面命名空间"是什么意思?实际上是什么意思?

更新时间:2023-02-20 11:09:40

说明

问题是由使用 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-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 的两个版本不好,请考虑以下情况:有两个库: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.