Я хочу интегрировать простую функцию C ++ в Python, используя Pybind11.
Рассмотрим следующий простой пример фиктивной функции:
#include <vector>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
// Dummy function: return a vector of size n, filled with 1
std::vector<int> generate_vector(unsigned int n)
{
std::vector<int> dummy_vector;
for(int i = 0; i < n; i++) dummy_vector.push_back(1);
return dummy_vector;
}
// Generate the python bindings for this C++ function
PYBIND11_PLUGIN(example) {
py::module m("example", "Generate vector of size n");
m.def("generate_vector", &generate_vector, "Function generates a vector of size n.");
return m.ptr();
}
Я храню этот код в функции с именем example.cpp
Я использую Python 3.5.2 с Anaconda. После официальная документация,
Составляю скрипт следующим образом:
c++ -O3 -shared -std=c++11 -I /Users/SECSCL/anaconda3/include/python3.5m `python-config --cflags --ldflags` example.cpp -o example.so
Я не знаю точно, что означает часть ‘python-config’, но я знаю, что это вызывает проблему. Я попробовал три варианта:
python3.4-config: это на самом деле работает и создает файл example.so. Но когда я пытаюсь загрузить его из python3.5, я получаю ошибку
Неустранимая ошибка Python: PyThreadState_Get: нет текущего потока
Таким образом, мой вопрос: как мне скомпилировать мой код, чтобы я мог загрузить его из python3.5? Или точнее: чем я должен заменить оператор ‘python-config’?
Я смог запустить ваш пример на моем MacOS Sierra MacBook Pro в начале 2015 года.
Я использовал твой example.cxx
Код без каких-либо изменений.
Перед тем как скомпилировать модуль, вы должны убедиться, что среда anaconda активна, чтобы команда компиляции вызывала python-config
команда.
В моем случае это было сделано с помощью: source ~/miniconda3/bin/activate
— вы, очевидно, должны заменить miniconda3
с anaconda3
,
Теперь дважды проверьте, что ваша команда компиляции вызовет правильный python-config
при выполнении: which python3.5-config
— это должно показать вам, что он использует ваш anaconda3 python3.5-config
,
Теперь вы можете запустить компиляцию следующим образом:
c++ -O3 -shared -std=c++11 -I $HOME/build/pybind11/include \
-I $HOME/miniconda3/include/python3.5m \
`python3.5m-config --cflags --libs` -L $HOME/miniconda3/lib/ \
example.cpp -o example.so
Обратите внимание, что мне пришлось добавить путь включения в мою проверку pybind11, указав точное python-config
версия (3,5 м), изменил --ldflags
в --libs
чтобы python-config
не добавил бы --stack-size
параметр ссылки, который будет вызывать ошибки, и, наконец, я добавил -L
для каталога miniconda3 (anaconda в вашем случае), содержащего libpython3.5m.dylib
После этого я мог сделать:
$ python
Python 3.5.2 |Continuum Analytics, Inc.| (default, Jul 2 2016, 17:52:12)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> v = example.generate_vector(64)
>>> print(v)
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
… что довольно аккуратно!
Других решений пока нет …