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