Hi to all!!!! In my recent project I'm working to allow a C user to
work with a Python Module which presents a C API but it's mainly
implemented writing Python code. The data structure passed between C
API calls might be a C structure containing Python objects as fields.
Here an example:

ctypedef public struct SpamManager:
  PySpam wrapper

cdef public api SpamManager* SpamManager_new():
  # Alloc and return a SpamManager structure
  ....

cdef public api int SpamManager_init( SpamManager* self, Spam* instance ):
  .....
  # Init the wrapper with the given instance
  self.wrapper = PySpam( instance )
  ....

cdef public api int SpamManager_doSomething( SpamManager* self ):
  # Do something with my nice wrapper :)
  ......

cdef public api void SpamManager_clear( SpamManager* self ):
  # Clear structure
  ....

cdef public api void SpamManager_delete( SpamManager* self ):
  # Delete structure
  ....

Spam is a C structure and PySpam is the correspondent Cython extension
type (or the Python wrapper, as you prefer :) ). The wrapper is
initialized passing a C instance to the constructor (casting the
instance to an unsigned long to obtain the pointer address). The
SpamManager module works with the PySpam wrapper but allows a C user
to
interact with the Python wrapper using the SpamManager structure and
function calls. The SpamManager structure must contain a PySpam field,
so we can avoid the overhead of the wrapper initialization creating it
only in the initialization phase (that is, in the SpamManager_init
function call).
The problem is that, in Cython, ctypedef-ed structures cannot have an
object field (so my SpamManager definition raises a compiler error).
I've partially rounded on the error declaring the wrapper attribute in
the SpamManager structure as a PyObject*, but this trick force me to
continually cast the wrapper attribute to <obejet> every time I need
to call a PySpam method using the wrapper instance. There's also the
problem that I've to allocate the wrapper like this:

  ....
  tmp = PySpam( instance )
  self.wrapper = <PyObject*>tmp
  ....

tmp is a temporary Python object, so it goes out of scope when the
function terminates and, consequently, I've to manage wrapper's
reference count.
Is there a way to declare a C structure which has Python types as
fields? Hints about different approaches to library implementation are
also welcome. :)

Thanks for you help (and excuse me for my poor english).

Daniele
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to