Подтвердить что ты не робот

Как сохранить имя класса С++ без изменений с Cython?

У меня есть класс С++ под названием Foo. Если я следую инструкциям Cython С++, мне нужно будет назвать класс Python по-другому, например, PyFoo. Однако мне действительно нужно вызвать класс Pooon Foo. Как это сделать эффективно?

Изменить: я пытаюсь связать существующую библиотеку С++, ранее связанную с Boost Python. По разным причинам я бы хотел проверить Cython. Поскольку с Boost: классы Python Python вызывались с тем же именем, что и в С++, я хотел бы продолжить это соглашение об именах. Это не требование Python (CPython), чтобы вызывать классы по-разному, но, похоже, это навязывается Cython, по крайней мере, в учебнике.

Я могу, конечно, использовать чистый модуль python для определения класса Foo, который вызывает PyFoo, но это кажется скучным и неэффективным.

4b9b3361

Ответ 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()