Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert python object to cython pointer

Tags:

cython

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)
like image 474
DikobrAz Avatar asked Dec 02 '12 14:12

DikobrAz


People also ask

Does Cython have pointers?

The Cython language uses the normal C syntax for C types, including pointers.

Is Cython object-oriented?

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.

What is Cdef in Python?

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.

What is Cimport?

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.


1 Answers

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)  
like image 190
DikobrAz Avatar answered Sep 23 '22 22:09

DikobrAz