Re: How to pass String BYREF to C function?

Andrew Wilson <[email protected]>
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
Hey Lynton,
  Your c code needs to properly terminate the string with a '\n' in order
for python to print the result correctly.
  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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.