Ошибка импорта модуля Cython после успешного catkin_make - PullRequest
2 голосов
/ 15 мая 2019

Я пытаюсь представить класс и метод 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)

Я протестировал размещение всего в одном модуле, и код работает нормально, но я бы предпочел иметь отдельные модули для облегчения сопровождения и разделения логики. Вся помощь приветствуется!

...