Re: How to pass String BYREF to C function?
"Lynton Grice" <[email protected]>
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
Thanks so much for the help guys, i really appreciate it J From: [email protected] [mailto:[email protected]] On Behalf Of Andrew Wilson Sent: 18 August 2010 02:59 PM To: Lynton Grice; [email protected] Subject: Re: [ctypes-users] How to pass String BYREF to C function? Hey Lynton, I guess the casting and create_stream_buffer was for not as pointed out by TP, the following seems to work fine.I'm really a hack at ctypes... stream = ctypes.c_char_p("hello world") exitResult = ctypes.c_char_p() result = executeUserExit(stream, ctypes.byref(exitResult)) Andrew On Wed, Aug 18, 2010 at 8:11 AM, Lynton Grice <[email protected]> wrote: Hi Andrew, Thanks for the help on this, great stuff. If I run the code from a C client I will get half the first string.... If I print out the exitResult like you specified below: print ctypes.c_char_p(exitResult.value).value I get the following output in WingIDE helloö So it works but what are those funny characters at the end of the string? It is not serious though, I am just curious... Do I need to change my C code to get rid of those funny characters? int executeUserExit(char *buffer, char **userExitResultBuffer){ int total_len; total_len = strlen(buffer) / 2; *userExitResultBuffer = (char*) malloc(total_len); strncpy(*userExitResultBuffer, buffer, total_len); return 0; } Thanks again Lynton From: [email protected] [mailto:[email protected]] On Behalf Of Andrew Wilson Sent: 18 August 2010 02:00 PM To: Lynton Grice Cc: [email protected]; [email protected] Subject: Re: [ctypes-users] How to pass String BYREF to C function? Lynton, The following code is a hack; keep in mind that python strings are immutable so your c_char_p variables can't be written to by the dll. Instead you should be using "create_string_buffer" for writeable strings. I wasn't so sure about the char** variable so I just made it an int pointer and then cast it back to a string once the result were in. import ctypes import os if __name__ == "__main__": if os.name=='nt': userExit = ctypes.cdll.LoadLibrary("libUserExits.dll") executeUserExit = userExit.executeUserExit stream = ctypes.create_string_buffer("hello world") exitResult = ctypes.c_uint(0) result = executeUserExit(stream, ctypes.byref(exitResult)) print result, stream.value, ctypes.c_char_p(exitResult.value).value print "Finished" On Wed, Aug 18, 2010 at 4:24 AM, Lynton Grice <[email protected]> wrote: Hi there, Thanks for the comments. Please note that this is just a test script so I am not fussed about the os.name....I can take all that extra out later....I just wanted to get it working for now. I tried out something like what you said but still no luck: import ctypes as c userExit = c.cdll.LoadLibrary("libUserExits.dll") executeUserExit = userExit.executeUserExit executeUserExit.argtypes = [c.c_char_p, c.POINTER(c.c_char_p)] executeUserExit.restype = c.c_int stream = (c.c_char * 20)(*list("hello world")) exitResult = c.c_char_p() result = executeUserExit(c.byref(stream), c.byref(exitResult)) print result print "Finished" I will keep trying with a couple options...thanks for the push in the right direction though, much appreciated Lynton From: [email protected] [mailto:[email protected]] Sent: 18 August 2010 09:46 AM To: Lynton Grice Subject: Re: [ctypes-users] How to pass String BYREF to C function? On Aug 17, 2010, at 8:08 PM, Lynton Grice wrote: Hi there, I have the following example C function that basically take 2 arguments and halves the first string and puts that result in the second argument. int executeUserExit(char *buffer, char **userExitResultBuffer){ int total_len; total_len = strlen(buffer) / 2; *userExitResultBuffer = (char*) malloc(total_len); strncpy(*userExitResultBuffer, buffer, total_len); return 0; } I have call this from C code happily, but am having trouble from Python. I created a DLL from the code above import ctypes as c import os if __name__ == "__main__": if os.name=='nt': userExit = c.cdll.LoadLibrary("libUserExits.dll") executeUserExit = userExit.executeUserExit executeUserExit.argtypes = [c.c_char_p, c.c_char_p] executeUserExit.restype = c.c_int stream = c.c_char_p() stream.value = "hello world" exitResult = c.c_char_p() result = executeUserExit(c.pointer(stream), c.byref(exitResult)) print result print "Finished" There is a lot wrong with this on a pure python-level. Please think of why you use __name__ == "__main__" and os.name for a script you clearly don't use somewhere else. But that's just a remark. The important thing here is that you have to create *arrays* of characters, the same as with C. Then you can create pointers or byref references for this. Something like this (untested): a = (c_char * 20)(*list("foobarbaz")) b = c_char_p() result = executeUserExit(byref(a), byref(b)) And of course the declaration of executeUserExit is wrong, you need argtypes to be [c.c_char_p, POINTER(c.c_char_p)] Diez ---------------------------------------------------------------------------- -- This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ ctypes-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ctypes-users ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ ctypes-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ctypes-users