RJ | 13 Aug 00:16 2010
RayS | 13 Aug 06:24 2010
Mark McMahon | 13 Aug 03:51 2010
Mark McMahon | 13 Aug 13:30 2010
Lynton Grice | 17 Aug 20:08 2010
Lynton Grice | 18 Aug 09:14 2010
Lynton Grice | 18 Aug 10:24 2010
Andrew Wilson | 18 Aug 14:00 2010
Lynton Grice | 18 Aug 14:11 2010
Andrew Wilson | 18 Aug 14:16 2010
Picon

Re: How to pass String BYREF to C function?

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 <lynton.grice <at> logosworld.com> 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: andrew.k.wilson <at> gmail.com [mailto:andrew.k.wilson <at> gmail.com] On Behalf Of Andrew Wilson
Sent: 18 August 2010 02:00 PM
To: Lynton Grice
Cc: deets <at> web.de; ctypes-users <at> lists.sourceforge.net


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 <lynton.grice <at> logosworld.com> 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: deets <at> web.de [mailto:deets <at> web.de]
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
ctypes-users <at> lists.sourceforge.net
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
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users

Gmane