Да, я знаю, что этот ответ довольно поздний, но решения, предоставленные ранее, либо устарели, либо решают проблему неясным образом.
Самая большая проблема с другими ответами заключается в том, что они используют pybind и необработанный интерфейс Python одновременно. С pybind вы можете использовать более простой и приятный интерфейс для интерпретатора.
После реализации, которая должна решить вашу проблему.
Первое, что вы заметите, это то, что мы используем заголовочный файл «embed.h». Это дает нам функции для создания встроенных модулей.
Ниже мы используем PYBIND11_EMBEDDED_MODULE
вместо обычного PYBIND11_MODULE
или устаревшего PYBIND11_PLUGIN
. Это макрос специально для встраивания.
Следующая интересная часть — это типы, которые мы определяем для нашей структуры. Кроме Dog
Type мы также используем shared_ptr<Dog>
. Это очень важно для работы с экземплярами. Когда модуль main
выходит из Scope и начинает очистку, он должен знать, что класс/структура имеет тип shared_ptr, иначе вы получите ошибку seg (необработанные указатели здесь не используются, я лично считаю, что это хорошо).
Последнее, на что следует обратить внимание, это то, что мы фактически используем класс pybind11::scoped_interpreter
для нашего интерпретатора и не используем интерфейс Raw Python.
#include"pybind11\pybind11.h"
#include"pybind11\embed.h"
#include<iostream>
namespace py = pybind11;
struct Dog {
void bark() { std::cout << "Bark!\n"; }
};
PYBIND11_EMBEDDED_MODULE(DogModule, m) {
// look at the types! we have a shared_ptr<Dog>!
py::class_<Dog, std::shared_ptr<Dog>>(m, "DogModule")
.def("bark", &Dog::bark);
}
int main(int argc, char **argv)
{
// Create Python Interpreter
py::scoped_interpreter guard;
// Create Dog Instance
std::shared_ptr<Dog> ptr = std::make_shared<Dog>();
// Import the DogModule & Assign the instance to a name in python
py::module main = py::module::import("__main__");
main.import("DogModule");
main.attr("dogInstance") = ptr;
// Call the bark method from python
py::exec("dogInstance.bark()");
getchar();
return 0;
}
person
Simerax
schedule
26.06.2018