libboost_python3.so.1.56.0: undefined symbol: PyClass_Type

libboost_python3.so.1.56.0: undefined symbol: PyClass_Type

本文关键字:undefined symbol Type PyClass python3 so libboost      更新时间:2023-10-16

我正在尝试使用boost:: Python库在c++中为Python 3创建一个helloWorld模块。

这是一个CmakeList.txt:

set(Python_ADDITIONAL_VERSIONS 3.4)
find_package( PythonLibs 3.4 REQUIRED )
include_directories( ${PYTHON_INCLUDE_DIRS} )
find_package( Boost 1.56.0 EXACT COMPONENTS python3 REQUIRED )
include_directories( ${Boost_INCLUDE_DIR} )
# Define the wrapper library that wraps our library
add_library( hello SHARED main.cpp )
target_link_libraries( hello ${Boost_LIBRARIES} ${PythonLibs_LIBRARIES} )
# don't prepend wrapper library name with lib
set_target_properties( hello PROPERTIES PREFIX "" OUTPUT_NAME hello)

main.cpp

#include <boost/python.hpp>
char const* greet( )
{
    return "Hello world";
}    
BOOST_PYTHON_MODULE(mymodule)
{
    using namespace boost::python;
    def( "greet", greet );
}

我从这里描述的源代码安装了boost库,但它不允许我使用boost-python3库(在Cmake中有一个错误)。为此,我使用

./bootstrap.sh --with-python-version=3.4 --prefix=/usr/local
不是

./bootstrap.sh --prefix=/usr/local

显式指定python的版本;

作为输出,我们得到一个共享库hello.so。一切似乎都很好。但是…

当我尝试将库导入python脚本script.py时,内容:

import hello

在终端使用命令…$ python3 script.py

我收到一个错误

Traceback (most recent call last):
  File "script.py", line 1, in <module>
    import hello 
ImportError: /usr/local/lib/libboost_python3.so.1.56.0: undefined symbol: PyClass_Type

问题是:如何使boost库与Python 3兼容?python2没有问题。但是我需要python3。当同样的错误发生时,我也看到了页面,但它没有帮助我。

我软件:

  • boost version 1.6.0
  • Python 3.4
  • cmake version 2.8.12.2
  • gcc 4.8.2
  • 操作系统:Ubuntu 14.04 LTS, 64位

正如这个回答所指出的:

PyClass_Type是Python 2 C API的一部分,而不是Python 3 C API的一部分。因此,出现了Boost。Python库可能是基于Python 2构建的。但是,它是由Python 3解释器加载的,其中PyClass_Type不可用。

没有给出产生libboost_python3.so的确切过程,所以我只能推测一个非干净的构建,比如构建Boost。Python with Python2,然后用Python3重新配置bootstrap,然后构建Boost。Python与Python2对象文件。无论如何,请验证Boost的干净的构建。Python with Python3.

$ ./bootstrap.sh --with-python=/usr/bin/python2
...
Detecting Python version... 2.7
$ ./b2 --with-python --buildid=2 # produces libboost_python-2.so
$ ./bootstrap.sh --with-python=/usr/bin/python3 --with-python-root=/usr
...
Detecting Python version... 3.3
$ ./b2 --with-python --buildid=3noclean # produces libboost_python-3noclean.so
$ ./b2 --with-python --clean
$ ./b2 --with-python --buildid=3 # produces libboost_python-3.so
$ nm -D stage/lib/libboost_python-2.so | grep PyClass_Type
                 U PyClass_Type
$ nm -D stage/lib/libboost_python-3noclean.so | grep PyClass_Type
                 U PyClass_Type
$ nm -D stage/lib/libboost_python-3.so | grep PyClass_Type

如预期的那样,libboost_python-2.so引用了PyClass_Type符号。此外,libboost_python-3noclean.so包含对PyClass_Type的引用,因为它是用libboost_python-2.so的目标文件构建的。在一个干净的构建中,libboost_python-3.so不应该包含对PyClass_Type的引用。