Re: ctypes-users Digest, Vol 49, Issue 4
"Mark Tolonen" <[email protected]>
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[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 ------------------------------------------------------------------------------ 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