[Pyrex] python callback appended to external C struct

Lenard Lindstrom len-l at telus.net
Sun Dec 4 22:34:28 CET 2005


I was curious myself if anyone knew of a safe way to go from a Python 
object to void pointer and back in Pyrex. Why not use a module level 
dictionary instead that maps object instances by object id. 
Wrap.__new__ would add the new object to the dictionary, and a 
Wrap.__dealloc__ would remove it. Then CWrapPositionPyrex.self is the 
id, as an integer, and dummy_cd retrieves the actual object from the 
dictionary and calls its cb method.

Lenard Lindstrom
<len-l at telus.net>

On 1 Dec 2005 at 16:22, Elias Pschernig wrote:

> Hi, after some fiddling, I got my external library to call back a python
> method, but I had to actually wrap an external struct into another
> struct with an extra "void *" at the end. Anyone knowing internals of
> Pyrex/Python can confirm that this should be safe to use? And is this a
> good way, or is there a better one?
> 
> ---- cwrap.c ----
> #include "cwrap.h"
> void cwrap_test(CWrapPosition *self)
> {
>     self->cb(self);
> }
> 
> ---- cwrap.h ----
> typedef struct CWrapPosition CWrapPosition;
> struct CWrapPosition
> {
>     void (*cb)(CWrapPosition *self);
> };
> void cwrap_test(CWrapPosition *self);
> 
> ---- wrap.pyx ----
> cdef extern from "cwrap.h":
>     ctypedef struct CWrapPosition:
>         void *cb
>     void cwrap_test(CWrapPosition *self)
> 
> cdef struct CWrapPositionPyrex:
>     CWrapPosition wrapped
>     void *self # any other way to do it?
> 
> cdef dummy_cb(CWrapPositionPyrex *wrapped):
>     self = <object>wrapped.self # will this always work?
>     self.cb()
> 
> cdef class Wrap:
>     cdef CWrapPositionPyrex wrapped
> 
>     def __new__(self):
>         self.wrapped.wrapped.cb = <void *>dummy_cb
>         self.wrapped.self = <void *>self
> 
>     def test(self):
>         # actually, the cb will get called by the external library
>         # at undefined times (but from the same thread)
>         cwrap_test(&self.wrapped.wrapped)
> 
> --- test.py ----
> import wrap
> 
> class MyPythonClass(wrap.Wrap):
> 
>     def cb(self):
>         print "hello from", self.name
> 
> my_python_object = MyPythonClass()
> my_python_object.name = "my_python_object"
> my_python_object.test()
> 
> -- 
> Elias Pschernig
> 
> 
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
> 





More information about the Pyrex mailing list