更新时间:2023-02-20 11:09:40
问题是由使用 libc++
编译的对象和使用 libstdc++
编译的对象混合引起的.
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-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.