calldll & PyArg_ParseTuple strings

Scott McClellan 801d at my-deja.com
Wed Jul 7 16:33:40 EDT 1999


Thanks, Gordon, this works for me now. I still have a few more questions
regarding the PyArg_ParseTuple input format strings used in
calldll.call_foreign_function:

1- If I want to pass a long int by value from Python to the C/C++ DLL,
do I still use 'l' in the format string?  All of the examples I've seen
deal with parameters of type long*, rather than type long.

2- How do I handle DLL functions which expect parameters of type
unsigned char*, i.e. addresses of buffers into which the function copies
a fixed amount of binary data (may include '\000' byte values). I've had
some luck passing the name of a Python string and using 's' or 's#' in
the format string, but some of my results appear truncated, and the DLL
functions do not return a length associated with the data returned in
the buffer (required for 's#'?).  Also, since Python strings are
supposed to be immutable, having the DLL stuff them with data doesn't
seem to be a good idea.

Any help would be appreciated.

Regards,
Scott

In article <000016b8 at bossar.com.pl>,
  "Gordon McMillan" <Gordon.McMillan at p98.f112.n480.z2.fidonet.org>
wrote:
> From: "Gordon McMillan" <gmcm at hypernet.com>
>
> Scott McClellan writes:
> >
> > I'm attempting to use Sam Rushing's calldll module to call a C
> > function in a dll, with the following prototype:
> >
> > long __declspec(dllexport)func(long *x, long *y, long *z)
> >
> > I expect the function to give certain values back in x, y, and z,
> > but so far have been unable to make that happen. Let's say that I
> > have three long integers in Python that I initialize as follows:
> >
> > x=y=z=0L
>
> A Python int is a C long. You won't find a Python long in C.
>
> > My question is, in the following call from Python,
> >
> > call_foreign_function(pFunc, 'lll', 'l', (<?>,<?>,<?>))
> >
> > what should the tuple (<?>,<?>,<?>) contain?
>
> params = calldll.membuf(12)
> params.write('\000'*12)
> px = params.address()
> call_foreign_function(pFunc, 'lll', 'l', (px, px+4, px+8))
> rslt = params.read(0,12)
> x,y,z = struct.unpack('lll', rslt)
>
> Actually, Sam's got a slicker way of doing it, but I don't understand
> how it works, so I'll stick with the dumb-but-effective method.
>
> > If I pass (x,y,z), the
> > Python interpreter (Idle in my case) crashes, and this is
> > understandable, since it results in the contents of x, y, and z
> > being used as addresses to write to.  I've tried
> > (id(x),id(y),id(z)), since id() is supposed to return the address of
> > a Python object - Python didn't crash as before, but nothing was
> > copied into x, y, and z, either.
>
> id returns the address as a string. You wouldn't want this anyway.
> The Python int 0 is not a slot - it IS the one and only int object
> with value 0. If the foreign function were to return a 3 into the
> Python int (which it wouldn't - it would clobber something else in
> the struct) you would then have
>
> >> 3 + 0
> 6
>
> (The most commonly used ints are static singletons - try
>  sys.getrefcount(0))
>
> - Gordon
>
>


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




More information about the Python-list mailing list