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