Привет, мир с Boost Python и Python 3,2 - PullRequest
7 голосов
/ 25 августа 2011

Итак, я пытаюсь связать Python 3.2 и C ++ с помощью Boost Python, и столкнулся с множеством проблем. Я наконец получил его для компиляции с использованием библиотек 2.7, и он работает, но я не могу заставить его работать с Python 3.2.

Вот код C ++

#include <iostream>

using namespace std;

void say_hello(const char* name) {
    cout << "Hello " <<  name << "!\n";
}

int main(){return 0;}

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(hello)
{
    def("say_hello", say_hello);
}

Если я скомпилирую его с использованием библиотек 2.7, он работает просто отлично, но когда я использую библиотеки 3.2, я получаю тонны неопределенных ссылок из libboost_python.so

В противном случае я написал немного Python, чтобы он работал:

from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
    ext_modules=[
        Extension("hello", ["testBoost.cpp"],
        libraries = ["boost_python"])
    ])

и это создаст сборку с использованием Python 3.2 или 2.7, но когда я открою интерпретатор python 3 и попытаюсь импортировать его, он снова выдаст мне неопределенный символ PyClass_Type из libboost_python.so. Есть идеи? Совместим ли Boost Python с Python 3.x?

Если информация полезна, вот моя попытка компиляции с использованием 3.2:

   $ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python -lpython3.2mu 
    /tmp/ccdmU1Yu.o: In function `PyInit_hello':
    testBoost.cpp:(.text+0xc2): undefined reference to `boost::python::detail::init_module(PyModuleDef&, void (*)())'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_Size'
    /usr/local/lib/libboost_python.so: undefined reference to `PyFile_FromString'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_Type'
    /usr/local/lib/libboost_python.so: undefined reference to `PyInt_Type'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_FromString'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_FromStringAndSize'
    /usr/local/lib/libboost_python.so: undefined reference to `Py_InitModule4_64'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_FromFormat'
    /usr/local/lib/libboost_python.so: undefined reference to `PyNumber_Divide'
    /usr/local/lib/libboost_python.so: undefined reference to `PyNumber_InPlaceDivide'
    /usr/local/lib/libboost_python.so: undefined reference to `PyInt_AsLong'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_InternFromString'
    /usr/local/lib/libboost_python.so: undefined reference to `PyClass_Type'
    /usr/local/lib/libboost_python.so: undefined reference to `PyString_AsString'
    /usr/local/lib/libboost_python.so: undefined reference to `PyInt_FromLong'
    /usr/local/lib/libboost_python.so: undefined reference to `PyFile_AsFile'
    collect2: ld returned 1 exit status

И ошибка интерпретатора Python 3

File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/libboost_python.so.1.47.0: undefined symbol: PyClass_Type

Спасибо за любую помощь!

Ответы [ 4 ]

8 голосов
/ 19 июля 2012

У меня была точно такая же проблема, с Ubuntu 12.04.Я установил версию библиотеки 1.48 и должен был ссылаться на libboost_python-py32.so вместо libboost_python.so. После этого ошибки компоновщика исчезли.

5 голосов
/ 26 августа 2011

Приведенный выше код c ++ компилируется в модуль с

$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python3 -lpython3.2mu -o hello.so -shared

Эта команда компиляции добавляет -lboost_python3 и -shared, а также соглашение об именах для модулей расширения Python. Вам также следует установить пакет python3-dev и настроить / собрать / установить буст с python3, если вы этого еще не сделали.

В Python 3 я могу сделать следующее:

$ python3
Python 3.2 (r32:88445, Mar 25 2011, 19:28:28) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.say_hello('bill')
Hello bill!
>>>

В этот момент вы должны участвовать в гонках.

1 голос
/ 22 августа 2018

Ссылки в библиотеках python (например, -L / usr / lib / x86_64-linux-gnu -lpython2.7 в linux или find_package (PythonLibs) в CMake 1 ) приведут к устранению этой проблемы компоновщикапрочь.

Вот более подробное объяснение проблемы ниже.В командной строке

$ nm --dynamic <path-to>/libboost_python.so | grep PyString_Size

Если вы чувствуете себя ленивым и предполагаете, что ваш libboost_python ссылается на python2.7, просто запустите этот

$ nm --dynamic `locate libboost_python27.so | awk 'NR==1'` | grep PyString_Size

Вы должны увидеть что-то вроде

U PyString_Size

Так что PyString_Size не определен (U) в libboost_python27.so.Это то, на что жаловался компоновщик.Мы подтвердили это.Теперь давайте посмотрим на этот символ в libpython.

$ nm --dynamic `locate libpython2.7.so | awk 'NR==1'` | grep PyString_Size

На моей машине я увидел что-то вроде этого:

00000000000f0530 T PyString_Size

T указывает, что текст для этого символа находится наадрес указан.Так что это доказательство того, что мы не связывали в libpython в дополнение к libboost_python.

1 Почему вы не используете CMake?:)

1 голос
/ 15 августа 2015

Хотя это обсуждение старое, просто для записи: измените project-config.jam, чтобы изменить версию Python на свою настройку

# Python configuration
using python : 3.4 : /usr ;

Затем создайте надстройку:

./b2 clean
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release stage
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release install

более поздняя команда требует привилегий суперпользователя.Затем перейдите в папку, содержащую код C ++ для расширения:

g++ -std=c++11 hellopy.cpp -I/usr/include/python3.4 -I/usr/local/include/boost/python -lboost_python3  -o hello.so -shared -fPIC

Затем вы можете импортировать hello в среду python.

...