Boost.Python __init__() должен возвращать None, а не NoneType
У меня есть целая куча работающего кода 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 ;
Инструкции по установке Boost.Python [0] кажутся мне неудачными, когда я пытаюсь собрать быстрый старт с bjam (много предупреждений), поэтому я попытался следовать инструкциям Boost Getting Started [1] для создания двоичного файла заголовка Python, что, я думаю, что вызывает эту проблему. Любые рекомендации относительно того, как это исправить, были бы удивительны, я потратил на это часы.
1 ответ
Эта ошибка, вероятно, из-за ссылки на неправильную библиотеку Python. Убедитесь, что ваше расширение и библиотека Boost Python связаны с установкой Python, которую вы используете для импорта модуля.
В Linux вы можете проверить, с какими библиотеками вы связаны ldd
, На OS X otool -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
,