Как сохранить имя класса С++ без изменений с Cython?
У меня есть класс С++ под названием Foo. Если я следую инструкциям Cython С++, мне нужно будет назвать класс Python по-другому, например, PyFoo.
Однако мне действительно нужно вызвать класс Pooon Foo. Как это сделать эффективно?
Изменить: я пытаюсь связать существующую библиотеку С++, ранее связанную с Boost Python. По разным причинам я бы хотел проверить Cython.
Поскольку с Boost: классы Python Python вызывались с тем же именем, что и в С++, я хотел бы продолжить это соглашение об именах. Это не требование Python (CPython), чтобы вызывать классы по-разному, но, похоже, это навязывается Cython, по крайней мере, в учебнике.
Я могу, конечно, использовать чистый модуль python для определения класса Foo, который вызывает PyFoo, но это кажется скучным и неэффективным.
Ответы
Ответ 1
Есть два способа справиться с этим.
-
Объявить класс С++ с альтернативным именем; оригинальное имя должно быть указано в двойных кавычках:
cdef extern from "defs.h" namespace "myns":
cdef cppclass CMyClass "myns::MyClass":
...
Затем вы можете использовать MyClass
для своего класса python и ссылаться на объявление С++ как CMyClass
.
Обратите внимание, что исходное имя должно содержать пространство имен явно (если оно находится в пространстве имен).
Аргументы шаблона Cython (если они есть) должны идти после объявления альтернативного имени.
-
Объявите свои классы С++ в отдельном файле .pxd
, который по иному отличается от вашего файла .pyx
, а затем импортируйте его с помощью cimport
.
В cpp_defs.pxd:
cdef extern from "defs.h" namespace "myns":
cdef cppclass MyClass:
...
В py_wrapper.pyx:
cimport cpp_defs as cpp
cdef class MyClass:
cpp.MyClass *_obj
Ответ 2
Вот полный пример, демонстрирующий подход Никиты:
cdef extern from "floorplan_geometry.h" namespace "flyby::localize":
cdef cppclass CFloorplan "flyby::localize::Floorplan":
int xmin()
cdef class Floorplan:
cdef CFloorplan* obj_
def __cinit__(self):
self.obj_ = new CFloorplan()
def __dealloc__(self):
del self.obj_
def xmin(self):
return self.obj_.xmin()