【问题标题】:libboost_python3.so.1.56.0: undefined symbol: PyClass_Typelibboost_python3.so.1.56.0:未定义符号:PyClass_Type
【发布时间】:2014-10-01 01:39:59
【问题描述】:

我正在尝试使用 boost::python 库在 C++ 中为 Python3 创建一个 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 );
}

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

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

而不是

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

明确指定python的版本;

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

当我尝试将库导入 python 脚本sript.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库兼容python3? python2 没有问题。但我需要python3。 当同样的错误发生时,我也看到了page,但这对我没有帮助。

我的软件:

  • 提升版本 1.56.0
  • pyhton 3.4
  • cmake 版本 2.8.12.2
  • gcc 4.8.2
  • 操作系统:Ubuntu 14.04 LTS,64 位

【问题讨论】:

标签: c++ python-3.x boost cmake boost-python


【解决方案1】:

正如answer 中所述:

PyClass_Type 是 Python 2 C API 的一部分,而不是 Python 3 C API 的一部分。因此,Boost.Python 库很可能是针对 Python 2 构建的。但是,它是由 Python 3 解释器加载的,其中 PyClass_Type 不可用。

没有给出用于产生libboost_python3.so的确切过程,所以我只能推测一个不干净的构建,例如用Python2构建Boost.Python,然后用Python3重新配置引导程序,然后用Python2构建Boost.Python目标文件。无论如何,使用 Python3 验证 Boost.Python 的 clean 构建。

$ ./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 的引用。

【讨论】:

  • 构建后,我应该如何修改CmakeList.txt 以供使用这些特定目录中的这些库?因为错误是相同的,所以在我重建项目并在此库中包含其他目录之后。 Cmake 输出没有任何变化。
  • 我还尝试手动包含 *.so 文件:在 CMakeList.txt 文件中指定新的 libboost_python-3.so 而不是 ${Boost_LIBRARIES} 的路径:target_link_libraries( hello "/home/john/soft /boost/boost_1_56_0/stage/lib/libboost_python-3.so" ${PythonLibs_LIBRARIES} )。 yield is new 又一个错误:ImportError: dynamic module does not define init function (PyInit_hello)
  • @IvanBereziuk 库和模块名称必须匹配。将库构建为 mymodule.so 或使用 BOOST_PYTHON_MODULE(hello) 将模块命名为 hello
  • 耶!!!它可以工作(如果我手动包含*.so)。但这不是问题的最佳解决方案(手动指定库的路径)。当你需要使用多个 boost 库时该怎么办?如何将我们的库集成到常用的${Boost_LIBRARIES}
  • 是的,我找到了解决方案。不知何故,新的 boos::python3 库的名称为 libboost_python-3.so(用于与旧的 libboost_python3.so 进行比较。所以我在 python-3 上更改了 python3 并且模块开始导入而没有错误。
猜你喜欢
  • 2013-11-20
  • 1970-01-01
  • 2022-10-25
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
相关资源
最近更新 更多