Re: writing to a c_char_p received in a callback
Larry Bugbee <[email protected]> Sun, 10 Jul 2011 01:22:52 -0700
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
> 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