Я пытаюсь представить класс и метод C ++ для Python. Поэтому я решил использовать Cython, чтобы обернуть их. Код C ++ является частью пакета catkin, поэтому я исследовал способы интеграции компиляции Cython внутри catkin_make
.
В моем фиктивном примере есть класс C ++ A
и фабричный метод get_a()
, который возвращает shared_ptr<A>
. На стороне Cython я создал одну пару файлов example_a.pxd
и example_a.pyx
, которые обертывают класс C ++ A
в PyA
, и c_example_a_factory.pxd
и example_a_factory.pyx
, которые обертывают метод C ++ get_a()
в метод Cython то же имя. Я и import
и cimport
класс PyA
с example_a
модуля на example_a_factory
, и он хорошо компилируется. Однако, когда я пытаюсь импортировать example_a_factory
из python, я получаю сообщение об ошибке:
ImportError: No module named example_a
Я нашел несколько репозиториев, которые пытаются выполнить нечто похожее на то, что мне нужно, в отношении процесса сборки, и я последовал этим примерам: ros_cython_example , cython_catkin_example , cython_cmake_example
Вы можете найти мой пример кода в этом репо вместе с инструкциями по его запуску. Для удобства я также публикую здесь файлы Cython:
example_a.pxd
from libcpp.memory cimport shared_ptr
cdef extern from "catkin_cython_example/example_a.hpp" namespace "example_a":
cdef cppclass A:
int get() const
cdef class PyA:
cdef shared_ptr[A] c_a # Hold a C++ instance which we're wrapping
@staticmethod
cdef inline create(shared_ptr[A] c_a):
cdef PyA py_a = PyA()
py_a.c_a = c_a
return py_a
example_a.pyx
from cython.operator cimport dereference as d
cdef class PyA:
def get(self):
cdef int v = d(self.c_a).get()
return v
c_example_a_factory.pxd
from libcpp.memory cimport shared_ptr
from example_a cimport A
cdef extern from "catkin_cython_example/example_a_factory.hpp" namespace "example_a_factory":
shared_ptr[A] get_a(int val) except +
example_a_factory.pyx
from libcpp.memory cimport shared_ptr
cimport c_example_a_factory
from example_a cimport A, PyA
from example_a import PyA
def get_a(val):
cdef shared_ptr[A] c_a = c_example_a_factory.get_a(val)
return PyA.create(c_a)
Я протестировал размещение всего в одном модуле, и код работает нормально, но я бы предпочел иметь отдельные модули для облегчения сопровождения и разделения логики. Вся помощь приветствуется!