I have a C++ class called Foo. If I follow the Cython C++ tutorial I will need to call the Python class differently, PyFoo for example. However I really need to call the Python class Foo as well. How to do that efficiently?
Edit: I'm trying to interface an existing C++ library that was previously interfaced with Boost Python. For different reasons I would like to test Cython instead. Since with Boost:Python Python classes were called with the same name as in C++, I would like to continue with this naming convention. It's not a Python (CPython) requirement to call classes differently, but it seems to be imposed by Cython, at least in the tutorial.
I can of course use a pure python module to define a Foo class that calls PyFoo, but this seems both boring and inefficient.
Cython is a programming language that blends Python with the static type system of C and C++. cython is a compiler that translates Cython source code into efficient C or C++ source code. This source can then be compiled into a Python extension module or a standalone executable.
Cython has native support for most of the C++ language. Specifically: C++ objects can be dynamically allocated with new and del keywords. C++ objects can be stack-allocated.
Advantages of the Cython Programming Language The Cython programming language is used to speed the written codes. Cython language allows easy working with the C libraries. Cython also supports C++. Cython allows easy interaction with the Python Libraries without Python in the way.
There are two ways to handle this.
Declare C++ class with an alternate name; original name has to be specified in double quotes:
cdef extern from "defs.h" namespace "myns":
cdef cppclass CMyClass "myns::MyClass":
...
Then you can use MyClass
for your python class and refer to C++ declaration as CMyClass
.
Note that original name has to include the namespace explicitly (if it is namespaced). Cython template arguments (when present) should go after an alternate name declaration.
Declare your C++ classes in a separate .pxd
file, named differently from your .pyx
file, then import them with cimport
.
In cpp_defs.pxd:
cdef extern from "defs.h" namespace "myns":
cdef cppclass MyClass:
...
In py_wrapper.pyx:
cimport cpp_defs as cpp
cdef class MyClass:
cpp.MyClass *_obj
Here is a full example demonstrating Nikita's approach:
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With