Re: writing to a c_char_p received in a callback
"Matt Herbert (matherbe)" <[email protected]> Mon, 11 Jul 2011 08:14:19 -0500
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
Larry, Thanks for the response. I think I was not clear enough with my initial description. I'm loading a shared library that uses a callback function to set its data. So, I need to define the callback in python, not simply call a function in the shared lib. -----Original Message----- From: Larry Bugbee [mailto:[email protected]] Sent: Sunday, July 10, 2011 4:23 AM To: [email protected] Subject: Re: [ctypes-users] writing to a c_char_p received in a callback > I have a callback function that would be defined like this in C: > > > > #define MY_DATA = "abcdefg" > > int set_data_cb(void *unused, char *buf, int* bufsize) { > (*bufsize) = (int)strlen(MY_DATA) > strncpy(buf, MY_DATA, (*bufsize)) > } > > Of course this is simplified, but the idea is the caller is passing the > callback func a pointer to a string, which the callback function is > responsible for adding data to. I'm having an awfully hard time getting > this to work with ctypes. It seems that ctypes is automatically > converting my c_char_p into a normal python str, which of course does > not allow me to update the original char* that was passed into the > callback. > > I've tried several different variations: > > 1) CB_FUNC_INPUT =CFUNCTYPE(c_int, c_voidp, c_char_p, > POINTER(ctypes.c_int)) > # This gives me a python str ... no good > > 2) class my_c_char_p(ctypes.c_char_p): pass > CB_FUNC_INPUT =CFUNCTYPE(c_int, c_voidp, my_c_char_p, > POINTER(ctypes.c_int)) > # this gives me a my_c_char_p object, but updating the value property > doesn't seem to get my data back to the caller > > 3) CB_FUNC_INPUT =CFUNCTYPE(c_int, c_voidp, POINTER(c_char_p), > POINTER(ctypes.c_int)) > # this gives me a pointer, but settings contents.value also does not get > my data back to the caller > > 4) CB_FUNC_INPUT =CFUNCTYPE(c_int, c_voidp, c_void_p, > POINTER(ctypes.c_int)) > # argh, this gives me a long, not a pointer. (I was hoping I could just > cast it, but no luck) > > I've googled this to death, but either I have not found the magic > combination of search terms, or the answer is so obvious that nobody > else has had this problem. > > Any help would be appreciated! > > TIA > > -Matt Consider something like this. (tested on OSX) C lib: ------- #include "string.h" #define MY_DATA "abcdefg" void set_data_cb(void *unused, char *buf, int *bufsize) { // should test *bufsize > strlen(MY_DATA) strncpy(buf, MY_DATA, strlen(MY_DATA)); buf[strlen(MY_DATA)]='\0'; } Python pgm: ------------ from ctypes import * LIB = CDLL('libxxx.so') bufsize = c_int(20) buf = c_buffer(bufsize.value) LIB.set_data_cb(None, buf, bufsize) print ' %s, len=%d' % (buf.value, len(buf.value)) OSX compilation and execution: ------------------------------- gcc -dynamiclib -o libxxx.so libxxx.c python pgm.py Larry ------------------------------------------------------------------------ ------ All of the data generated in your IT infrastructure is seriously valuable. Why? It contains a definitive record of application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-d2d-c2 _______________________________________________ ctypes-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ctypes-users ------------------------------------------------------------------------------ All of the data generated in your IT infrastructure is seriously valuable. Why? It contains a definitive record of application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-d2d-c2