-----Original Message----- From: eryk sun [mailto:eryk...@gmail.com] Sent: 03 August 2016 13:16 To: python-list@python.org Cc: Bill Somerville <bsomervi...@flexerasoftware.com> Subject: Re: Issue with ctypes and callback functions
On Wed, Aug 3, 2016 at 9:38 AM, Bill Somerville <bsomervi...@flexerasoftware.com> wrote: > > Is this a good place to ask questions about the above? Discussing ctypes is fine here. There's also a ctypes-users list. Thanks Eryk, I am trying to handle Python callback functions in a SWIG interface, SWIG does not support callbacks where the target is a Python callable but I can do this with ctypes. My problem is that I need to have the callback receive a SWIG wrapped type as an argument by reference. I see that if I use a ctypes.Structure type then it works nicely but I have a huge and changing API to wrap and do not want to manually describe every C struct with ctypes.Structure when SWIG has already automatically created its own shadow classes. The SWIG struct wrapper is just a class wrapping a pointer so can be easily be passed just like ctypes.Structure can be. How do I tell ctypes that it needs to reconstitute the type from an address in the callback thunk it generates? I have tried defining from_param() and self._as_parameter_ for the types which works for passing to a function but I don't need that as SWIG does that already. With callback arguments I get various errors depending on what methods/attributes I supply like: Parsing argument 0 TypeError: cannot build parameter At the point where the callback is being called. To summarize: ++++++++++++++++++++++++++++++++++++ C API like: typedef struct { int member; /* ... */ } my_type; typedef int (*pfn) (my_type const *); int fn (pfn); Implementation could be: #include "api.h" int fn (pfn cb) { my_type t = {42, /* ... */}; return cb (&t); } I want Python code like: from ctypes import * import api # SWIG extension module def my_cb (t): print ('in callback with:', t.member) return 0 proto = CFUNCTYPE (c_int, my_type) cb = proto (my_cb) res = api.fn (cast (cb, c_void_p).value) print ('fn returned:', res) ------------------------------------------------ I can extend the SWIG shadow class to do the creation of the prototype and thunk, the required cast above and any extra attributes or methods like _as_parameter_ and from_param() but I can't see any way of having the Python callback (my_cb) magically receive the SWIG wrapped 'my_type' struct. TIA Bill. -- https://mail.python.org/mailman/listinfo/python-list