Я пытаюсь обернуть модуль C ++, используя Cython, чтобы я мог использовать его в Python.
Модуль имеет несколько классов, некоторые из них имеют методы, которые имеют ссылки на объекты другого класса в качестве аргументов.
Допустим, у меня есть классы c ++ с именами «foo» и «bar» — и Cython оберните их так:
cdef extern from "foobar.hpp" namespace "foobar":
cdef cppclass foo:
pass
cdef cppclass bar:
void kungFoo(foo &f)
Теперь я хочу создать класс-оболочку, чтобы я мог использовать его в Python …
cdef class pyFoo:
cdef foo *thisptr
def __cinit__(self):
self.thisptr = new foo()
cdef class pyBar:
cdef bar *thisptr
def __cinit__(self):
self.thisptr = new bar()
def kungFoo(self, f):
self.thisptr.kungFoo(f.thisptr)
Ну, это приводит к «Ошибка компиляции файла Cython». и «Невозможно преобразовать объект Python в ‘foo'».
Я думаю, это потому, что cdef cppclass foo делает foo «объектом Python», связанным с классом c ++. Тем не менее, это умное преобразование, похоже, не идет в обратном направлении, когда мне нужно передать его в качестве аргумента другому классу c ++.
Мне кажется, это основная проблема с Cython, но я не могу найти никакого решения через пару часов в Google.
Любая помощь приветствуется.
Спасибо!
Укажите тип для параметра f. Так сделайте это так:
def kungFoo(self, foo &f):
self.thisptr.kungFoo(f)
Или это:
def kungFoo(self, pyFoo f):
self.thisptr.kungFoo(f.thisptr)
Второй раздел кода вышеупомянутого ответа должен работать, но вам может потребоваться изменить его, так как вы передаете по ссылке. Вы можете либо изменить указатель передачи, в котором не нужно вносить никаких изменений, либо импортировать модуль Cython разыменования, чтобы повернуть указатель на объект и назначить объект для ссылки.
Пример использования разыменования показан в ответе на Конструкторы классов Cython и C ++
Надеюсь, это поможет вам. Эта проблема заняла у меня много часов, и вышеприведенная страница была чрезвычайно полезной.
Чтобы передать класс по ссылке:
def kungFoo(self,pyFoo f):
self.thisptr.kungFoo(f.thisptr[0])