Re: [cython-users] Passing C pointers to Cython function

536 views
Skip to first unread message

Robert Bradshaw

unread,
Sep 27, 2012, 5:47:44 AM9/27/12
to cython...@googlegroups.com
On Thu, Sep 27, 2012 at 2:39 AM, Horace Abenga <horace...@gmail.com> wrote:
> Is it possible to pass pointers to defined types in Cython to constructors,
> for example:
>
> cdef extern from "Foo.h":
> cdef cppclass Bar:
> pass
>
> cdef class PyClass:
> cdef Bar *bar
>
> def __cinit__(self, Bar *b)
> bar = b
>
>
> When you do this, you get a Cannot convert Python object to 'Bar *'.
>
> (Copied from
> http://stackoverflow.com/questions/12204441/passing-c-pointer-as-argument-into-cython-function,
> the top answer there is convoluted and seems to be just wrapping a double,
> what I'm trying to do is a bit more complicated)
>
> I am using such a construct to implement a "Has-A" (composition)
> relationship between two types that are defined as structs in a C Library.
>
> In my code, the Class Bar has a non-trivial constructor, and the
> "constructor" for PyClass in C should receive a pointer to an initialized
> Bar object.
>
> Is there a simple way of doing this?

Python class construction requires a Python call, hence Python object
arguments. The two answers given on stackoverflow (writing a global
method that constructs the object then sets the pointer, or creating a
wrapper class for Bar you an pass around in Python space) are the
typical ways of handling this. There's not really anything "simpler"
(though that's pretty simple).

- Robert

Sturla Molden

unread,
Sep 27, 2012, 5:50:32 AM9/27/12
to cython...@googlegroups.com
On 27.09.2012 11:39, Horace Abenga wrote:
> Is it possible to pass pointers to defined types in Cython to
> constructors, for example:
>
> |cdefextern from "Foo.h":
> cdef cppclassBar:
> pass
>
> cdefclass PyClass:
> cdefBar *bar
>
> def __cinit__(self, Bar *b)
> bar= b|
>
>
> When you do this, you get a *Cannot convert Python object to 'Bar *'*.**

__cinit__ takes the same arguments as __init__.


Sturla









Sturla Molden

unread,
Sep 27, 2012, 6:03:35 AM9/27/12
to cython...@googlegroups.com
On 27.09.2012 11:39, Horace Abenga wrote:

> In my code, the Class *Bar* has a non-trivial constructor, and the
> "constructor" for *PyClass* in C should receive a pointer to an
> initialized *Bar* object.

Uaually this is an error of reasoning, as a non-trival constructor will
be non-trivial outside __cinit__ as well. So calling it from __cinit__
cannot be more difficult than calling it from anywhere else.

Sturla







Czarek Tomczak

unread,
Sep 27, 2012, 7:35:30 AM9/27/12
to cython...@googlegroups.com
For each cdef class create a global cdef function that acts as a constructor, CefResponse is a C++ object, PyResponse a python equivalent of a c++ object:

  1. cdef object CreatePyResponse(CefRefPtr[CefResponse] cefResponse):
  2.  
  3.     pyResponse = PyResponse()
  4.     pyResponse.cefResponse = cefResponse
  5.     return pyResponse
  6.  
  7. cdef class PyResponse:
  8.  
  9.     cdef CefRefPtr[CefResponse] cefResponse
  10.  
  11.     def GetStatus(self):
  12.  
  13.         return (<CefResponse*>(self.cefResponse.get())).GetStatus()

Czarek.
Reply all
Reply to author
Forward
0 new messages