8

我有一大堆工作的 C++ 代码,我想为其编写 Python 绑定。我正在尝试使用 Boost.Python,因为它似乎是让它工作的最简单方法,但它不合作。这是我正在尝试构建的扩展模块的部分代码:

BOOST_PYTHON_MODULE(libpcap_ext) {
    using namespace boost::python;
    class_<PacketEngine>("PacketEngine")
        .def("getAvailableDevices", &PacketEngine_getAvailableDevices);
}

Bjam 似乎很痛苦,拒绝识别我的 Pythonpath 或允许我与 libpcap 链接,所以我正在使用 CMake。这是我的 CMakeLists 文件,它可以很好地导入和构建所有内容(按预期输出 libpcap.so):

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
IF(NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "DEBUG")
  #SET(CMAKE_BUILD_TYPE "RELEASE")
  #SET(CMAKE_BUILD_TYPE "RELWITHDEBINFO")
  #SET(CMAKE_BUILD_TYPE "MINSIZEREL")
ENDIF()

FIND_PACKAGE(Boost 1.55.0)
find_package(PythonLibs REQUIRED)
IF(Boost_FOUND)
  INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "${PYTHON_INCLUDE_DIRS}")
  SET(Boost_USE_STATIC_LIBS OFF)
  SET(Boost_USE_MULTITHREADED ON)
  SET(Boost_USE_STATIC_RUNTIME OFF)
  FIND_PACKAGE(Boost 1.55.0 COMPONENTS python)

  ADD_LIBRARY(pcap_ext MODULE PacketWarrior/pcap_ext.cc PacketWarrior/PacketEngine.h PacketWarrior/PacketEngine.cc PacketWarrior/Packet.h PacketWarrior/Packet.cc)
  TARGET_LINK_LIBRARIES(pcap_ext pcap)
  TARGET_LINK_LIBRARIES(pcap_ext ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
ELSEIF(NOT Boost_FOUND)
  MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
ENDIF()

ADD_DEFINITIONS("-Wall")

我的 pcap.py 文件试图利用该模块:

import libpcap_ext
engine = libpcap_ext.PacketEngine()
print engine.getAvailableDevices()

但是每当我尝试运行该模块时,都会出现以下错误:

Traceback (most recent call last):
  File "../pcap.py", line 2, in <module>
    engine = libpcap_ext.PacketEngine()
TypeError: __init__() should return None, not 'NoneType

我假设这是因为 Boost.Python 正在尝试使用 Python 3,而我的系统默认是 Python 2.7.3。我尝试将我的 user-config.jam 文件(在我的 boost_1_55_0 目录中)更改为指向 Python 2.7 并尝试构建:

# Configure specific Python version.
# using python : 2.7 : /usr/bin/python2.7 : /usr/include/python2.7 : /usr/lib ;

当我尝试使用 bjam 构建快速入门(大量警告)时,Boost.Python 的安装说明 [0] 似乎失败了,所以我尝试按照 Boost Getting Started 说明 [1] 构建 Python 标头二进制文件,我认为是什么导致了这个问题。关于如何解决这个问题的任何建议都会很棒,我已经花了几个小时来解决这个问题。

4

1 回答 1

15

此错误可能是由于链接到错误的 Python 库。确保您的扩展以及 Boost Python 库与您用于导入模块的 Python 安装链接。

在 Linux 上,您可以检查您链接了哪些库ldd。在 OS Xotool -L上做同样的事情。所以,例如

otool -L libpcap_ext.so
otool -L /path/to/libboost_python-mt.dylib

应该列出它们链接的 Python 库。

使用 CMake,您可以使用该变量PYTHON_LIBRARY来更改使用的 Python 库。例如,在命令行上,您可以使用

cmake -DPYTHON_LIBRARY="/path/to/libpython2.7.dylib" source_dir

最后,在 OS X 上,更改动态链接库的一种快速而肮脏的方式(即无需重新编译)是install_name_tool -change.

于 2014-01-10T19:19:34.417 回答