I'm trying to expose c++ classes to python using cython. I wrote their definitions in *.pxd file and implemented a wrappers in *.pyx files. But I got stuck trying to pass to a function pointer to the extension type. Here is simplified example.
foo.pyx
from c_foo cimport cFoo
cdef class Foo:
cdef cFoo* _impl
c_foo_holder.pxd
cdef extern from "FooHolder.h":
cdef cppclass cFooHolder:
cFooHolder(cFoo* foo)
foo_holder.pyx
from c_foo_holder cimport cFooHolder
from c_foo cimport cFoo
cdef class FooHolder:
cdef cFooHolder* _impl
def __init__(self, foo):
self._impl = new cFooHolder(<cFoo*>(foo._impl)) # error here
But on the last line I get error "Python objects cannot be cast to pointers of primitive types". I also tried several other approaches, but nothing worked:
# error: 'Foo' is not a type identifier
from foo import Foo
def __init__(self, Foo foo):
self._impl = new cFooHolder(foo._impl)
# error: 'Foo' is not a type identifier
def __init__(self, foo):
self._impl = new cFooHolder(<Foo>(foo)._impl)
The Cython language uses the normal C syntax for C types, including pointers.
Cython is fast at the same time provides flexibility of being object-oriented, functional, and dynamic programming language. One of the key aspects of Cython include optional static type declarations which comes out of the box.
cdef declares function in the layer of C language. As you know (or not?) in C language you have to define type of returning value for each function. Sometimes function returns with void , and this is equal for just return in Python. Python is an object-oriented language.
c file). The cimport statement is used by Cython to import definitions from a . pxd file. This is different than using a normal Python import statement, which would load a regular Python module.
I found the solution. You have to tell cython that foo._impl is really cFoo* instance. That can be achieved by providing Foo definition (e.g. in foo.pxd). Afterwards you are able to cast python object to Foo and cython will know that its _impl field has type cFoo*.
foo.pxd
from c_foo cimport cFoo
cdef class Foo:
cdef cFoo* _impl
foo.pyx
from c_foo cimport cFoo
cdef class Foo:
# methods implementation
c_foo_holder.pxd
cdef extern from "FooHolder.h":
cdef cppclass cFooHolder:
cFooHolder(cFoo* foo)
foo_holder.pyx
from c_foo_holder cimport cFooHolder
from c_foo cimport cFoo
from foo cimport Foo
cdef class FooHolder:
cdef cFooHolder* _impl
def __init__(self, foo):
self._impl = new cFooHolder((<Foo?>foo)._impl)
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