Re: ctypes-users Digest, Vol 49, Issue 4
"Mark Tolonen" <[email protected]>
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
"Mark Tolonen" <[email protected]> wrote in message news:[email protected]... > > "Mads Kiilerich" <[email protected]> wrote in message > news:[email protected]... >> Adam Morris wrote, On 06/12/2010 06:44 AM: >>> >>> AFAIK ctypes should handle GIL correctly automatically, also when >>> used from threads. >>> >>> >>> Sure am glad to hear that! >>> >>> To me it sounds more like a problem with bad alignment or bad >>> parameter >>> >>> profile of the callback function. >>> >>> >>> I don't know about bad alignment, but you may be right around the bad >>> parameter profile. I think I've narrowed down the problem to the >>> context argument that is being passed to the SetCallback function of >>> the dll. If I pass it null or 0 or pointer() or even byref(), the >>> result is a bus error of 0x00 when it actually calls the callback, but >>> if I pass it 10 it gives a bus error with address of 0x0a. I'm >>> confused because the example files of the SDK show the C code passing >>> a "0" for the context argument, so then why would it spell trouble >>> using that from Python? Even weirder, if I don't pass any context >>> parameter at all to the SetCallback function, I get the exact same >>> error (or is this because I don't understand how parameter lists work >>> in C?) >>> >> >> It seems like the lib uses and dereferences pContext. You have to give >> it something it likes. >> >> You could try to make a little C application that tests this API and >> calls the callback. Try to do it without using the SDK .h files - create >> your own and simplify them as much as possible. That will help you get >> familiar with the API and take ctypes out of the equation. If you can't >> create such an application then you probably also can't do it with >> ctypes - unless you are lucky. >> >>> Here's all the relevant typedefs as defined in the SDK: >>> >>> >>> #Storage declarations: >>> >>> typedef signed int ax_int32_t >>> >>> typedef unsigned short ax_char16_t >>> >>> typedef unsigned int ax_handle_t >>> >>> # can't find AX_CALLCONV nor AX_API in the SDK >>> >>> >>> #Callback declaration: >>> >>> typedef void(AX_CALLCONV * ax_vote_callback_t)(ax_handle_t hubHandle, >>> ax_int32_t deviceSerialNumber, ax_int32_t vote, void *pContext) >>> >>> >>> Here's the SetCallback method I have to use, notice the context >>> argument: >>> >>> >>> AX_API ax_result_t AX_CALLCONV Ax_SetVoteCallback (ax_vote_callback_t >>> pfnCallback, void *pContext >>> >>> >>> Here's what I do in my own code, python 3.1 on Mac OS X, after "from >>> cytpes import *": >>> >>> >>> def set_vote_callback(self, python_function): >>> >>> self.keep_wrap_function_reference = CFUNCTYPE(c_void_p, >>> c_uint, c_int, c_int, c_void_p) >>> >> >> Shouldn't the first parameter (ax_handle_t) be an integer? >> >>> context = c_int(0) # no idea what to do here, honestly >>> >> >> Try to use None instead. >> >>> result = >>> self.cdll.Ax_SetVoteCallback(self.keep_wrap_function_reference(python_function), >>> context) > > The problem is in the line above. > self.keep_wrap_function_reference(python_function) creates a CFUNCTYPE > wrapper for the python function, but right after this call completes there > are no references to this wrapper and the object is deleted. Assign this > wrapped function to a variable that is still in scope when the callback > actually occurs and it will work. Something like: > > self.function_instance = > self.keep_wrap_function_reference(python_function) > result = self.cdll.Ax_SetVoteCallback(self.function_instance,context) > > HTH, > Mark Oh, and here's the relevant docs (at the very end of the section): http://docs.python.org/library/ctypes.html?highlight=ctypes%20tutorial#callback-functions "Important note for callback functions: Make sure you keep references to CFUNCTYPE objects as long as they are used from C code. ctypes doesn't, and if you don't, they may be garbage collected, crashing your program when a callback is made." -Mark ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo