Re: How to pass String BYREF to C function?
"Lynton Grice" <[email protected]>
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
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