Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing C++ pointer as argument into Cython function

Tags:

cdef extern from "Foo.h":     cdef cppclass Bar:         pass  cdef class PyClass:     cdef Bar *bar      def __cinit__(self, Bar *b)         bar = b 

This will always give me something like:
Cannot convert Python object argument to type 'Bar *'

Is there a way to accomplish this, or do I need to extract everything from a Bar object, create a Python equivalent, pass it in, then reconstruct it in PyClass?

like image 539
meteoritepanama Avatar asked Aug 30 '12 19:08

meteoritepanama


1 Answers

I came across this problem trying to wrap C code with structs as python classes. The issue seems to be that "special" function including __init__ and __cinit__ must be declared as def rather than cdef. This means that they can be called from normal python, so the type parameters are effectively ignored and everything is treated as object.

In J.F. Sebastian's answer the fix is not the wrapping - a double is a basic numeric type and so there is a default conversion between the C/C++ type and the Python object. Czarek's answer is basically correct - you need to use a fake constructor idiom, using a global function. It is not possible to use a @staticmethod decorator as they cannot be applied to cdef functions. The answer looks simpler on the original example provided.

cdef extern from "Foo.h":     cdef cppclass Bar:         pass  cdef class PyClass:     cdef Bar *bar  cdef PyClass_Init(Bar *b):     result = PyClass()     result.bar = b     return result 
like image 152
Andrew Avatar answered Sep 23 '22 13:09

Andrew