RJ | 13 Aug 00:16 2010

calling ' extern "C" int __declspec(dllexport) ' declared functions?

I am trying to access a win32 DLL with functions declared in the .h like this:
extern "C" int __declspec(dllexport) GetBlockSize( int& iBlockSize );
extern "C" int __declspec(dllexport) SetBlockSize( int iBlockSize );
extern "C" int __declspec(dllexport) GetData( int iChannel, float* rData );   

and I'm not getting anywhere. How do I call these three?

-Ray
------------------------------------------------------------------------------
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
RayS | 13 Aug 06:24 2010

Re: calling ' extern "C" int __declspec(dllexport) ' declared functions?

At 06:51 PM 8/12/2010, Mark McMahon wrote:
># can you get a reference the DLL
>dll = ctypes.windll.YOURDLLNAME

yes, it also wasn't immediately obvious that it was a cdecl (which I 
used with partial sucess), not a windll

>Can you get references to the functions...
>SetBlockSize = dll.SetBlockSize  #using SetBlockSize is easier as 
>the argument is a plain int
>
>ret = SetBlockSize = SetBlockSize(123)

it returns zero (apparently OK, by the .h file comment)

># does ret have the return code for success (or expected return value?)
>
>For GetBlockSize - you will need to read the doc and see what to do 
>with pointer/reference values :)  (but usually ctypes.byref(var) or 
>ctypes.pointer(var) are what you need).

I tried both byref and pointer, but both returned -1; I'll be talking 
to the hardware maker tomorrow

Do you write Python code for AutoCAD?

Thanks,
Ray 

------------------------------------------------------------------------------
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 
Mark McMahon | 13 Aug 03:51 2010

Re: calling ' extern "C" int __declspec(dllexport) ' declared functions?

Hi Ray,

The __declspec(dllexport) should not really impact things.

# can you get a reference the DLL
dll = ctypes.windll.YOURDLLNAME

Can you get references to the functions...
SetBlockSize = dll.SetBlockSize  #using SetBlockSize is easier as the argument is a plain int

ret = SetBlockSize = SetBlockSize(123)

# does ret have the return code for success (or expected return value?)

For GetBlockSize - you will need to read the doc and see what to do with pointer/reference values :)  (but
usually ctypes.byref(var) or ctypes.pointer(var) are what you need).

Thanks
  Mark

From: RJ [mailto:rays <at> blue-cove.com] 
Sent: Friday, August 13, 2010 6:17 AM
To: ctypes-users <at> lists.sourceforge.net
Subject: [ctypes-users] calling ' extern "C" int __declspec(dllexport) ' declared functions?

I am trying to access a win32 DLL with functions declared in the .h like this:
extern "C" int __declspec(dllexport) GetBlockSize( int& iBlockSize );
extern "C" int __declspec(dllexport) SetBlockSize( int iBlockSize );
extern "C" int __declspec(dllexport) GetData( int iChannel, float* rData );    

and I'm not getting anywhere. How do I call these three?

-Ray

------------------------------------------------------------------------------
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 
Mark McMahon | 13 Aug 13:30 2010

Re: calling ' extern "C" int __declspec(dllexport) ' declared functions?

Hi Ray,

> -----Original Message-----
> From: RayS [mailto:rays <at> blue-cove.com] 
> Sent: Friday, August 13, 2010 12:24 PM
> To: Mark McMahon; ctypes-users <at> lists.sourceforge.net
> Subject: RE: [ctypes-users] calling ' extern "C" int __declspec(dllexport) ' declared functions?
> 
> At 06:51 PM 8/12/2010, Mark McMahon wrote:
> ># can you get a reference the DLL
> >dll = ctypes.windll.YOURDLLNAME
> 
> yes, it also wasn't immediately obvious that it was a cdecl (which I 
> used with partial sucess), not a windll
> 
yes - cdl or windll - if one works - use it:)

> >Can you get references to the functions...
> >SetBlockSize = dll.SetBlockSize  #using SetBlockSize is easier as 
> >the argument is a plain int
> >
> >ret = SetBlockSize = SetBlockSize(123)
> 
> it returns zero (apparently OK, by the .h file comment)

So you can see the function, and you can evey call some of them :)

> 
> ># does ret have the return code for success (or expected return value?)
> >
> >For GetBlockSize - you will need to read the doc and see what to do 
> >with pointer/reference values :)  (but usually ctypes.byref(var) or 
> >ctypes.pointer(var) are what you need).
> 
> I tried both byref and pointer, but both returned -1; I'll be talking 
> to the hardware maker tomorrow

are you doing something like the following
val =  ctypes.c_int()
dll.GetBlockSize(ctypes.byref(val))

or
dll.GetBlockSize(ctypes.pointer(val))

Because the value will be modified - you need to create it separately first

> 
> Do you write Python code for AutoCAD?

I don't work on AutoCAD - but I use Python for automation tasks.
> 
> Thanks,
> Ray 

Hope that helps,
  Mark
> 

------------------------------------------------------------------------------
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 
Lynton Grice | 17 Aug 20:08 2010

How to pass String BYREF to C function?

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"     

            

 

I am not too sure how the BYREF and POINTER stuff should work in the above code?

 

I keep getting the error:

 

“ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type”

 

I have been reading online but cannot find any nice example to follow, can someone please give me some advise on this?

 

Your help is greatly appreciated ;-)

 

Lynton

------------------------------------------------------------------------------
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
Lynton Grice | 18 Aug 09:14 2010

Re: How to pass String BYREF to C function?

Hi Marco,

 

Thanks for the response, but I still get an error ;-(

 

ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type

 

I tried this code:

 

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.pointer(c.c_char_p())           

            result = executeUserExit(stream, exitResult)

     

      print "Finished"     

     

 

Do you have any other ideas?

 

Thanks for the help thus far ;-)

 

Lynton

 

From: marco cassisa [mailto:marco.cassisa <at> gmail.com]
Sent: 17 August 2010 09:51 PM
To: Lynton Grice
Subject: Re: [ctypes-users] How to pass String BYREF to C function?

 

Hi
I am absolutely no pro (just trying to use ctypes in these days), but AFICT c_char_p is equivalent to char*, while pointer(c_char_p) is equivalent to char**
So it seems to me that your C-declaration isn't equivalent to your ctypes'one
Hope not to be wrong...
bye

marco

2010/8/17 Lynton Grice <lynton.grice <at> logosworld.com>

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"     

            

 

I am not too sure how the BYREF and POINTER stuff should work in the above code?

 

I keep getting the error:

 

“ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type”

 

I have been reading online but cannot find any nice example to follow, can someone please give me some advise on this?

 

Your help is greatly appreciated ;-)

 

Lynton


------------------------------------------------------------------------------
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
Lynton Grice | 18 Aug 10:24 2010

Re: How to pass String BYREF to C function?

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
Andrew Wilson | 18 Aug 14:00 2010
Picon

Re: 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
Lynton Grice | 18 Aug 14:11 2010

Re: How to pass String BYREF to C function?

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
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