Struct and windll question (please help)
Gordon McMillan
gmcm at hypernet.com
Mon Dec 6 17:58:40 EST 1999
Calishar <calishar@*NOSPAM*home.com> wrote:
> I am trying to call the infozip unzip32.dll (on a windows 95
> system
> at the moment, but eventually on a winNT system too) in order to
> unzip a pkzip file (not gzip). Zlib doesn't seem to understand
> this type of file, so I am having to go outside standard python
> stuff.
>
> The calldll module has a function
> (call_foreign_function(address,
> input_args_format, result_args_format, argument_tuple)) which
> should be able to do what I need. What I am having problems with
> is constructing the format strings and tuple.
> The dll function I am calling has the following definition:
>
> Wiz_SingleEntryUnzip(int ifnc, char **ifnv, int xfnc, char
> **xfnv,
> LPDCL lpDCL, LPUSERFUNCTIONS lpUserFunc)
>
> where ifnv and xfnv can be Null. (I think the format code should
> be 'i255si255s??' (no idea for the structs) or (iPiP??) using the
> struct module codes. Or should I be using the codes from
> PyArg_ParseTuple? I am creating the two structs using struct.pack
> at the moment, is this right?
Maybe ;-). You need to create a buffer using calldll.membuf.
You can read and write to this buffer, and get the address of it.
Basically you need to fill this buffer with the C values (yes,
you can use struct) and then use buff.address() +
displacement where the C is expecting a pointer. Allocate
space in the buffer for out args, and read() them once the call
is done.
Here's an example from a dll whose name and purpose shall
remain nameless. The signature of the function is:
# status = accu_io_buffers_to_dib( BYTE ** DIB,
# BYTE * buff1,
# BYTE * buff2,
# BYTE * buff3,
# DWORD data_type,
# DWORD bits_per_pixel,
# DWORD rows,
# DWORD columns,
# DWORD free_flag)
and the code is:
def buffer_to_dib(buffer, rows, cols):
params = calldll.membuf(4)
params.write('\000'*4)
start = params.address()
paramfmt = 'l'
argfmt = 'l'*9
calltpl = ( start, #outbuff **
buffer, #buffer1
0, #buffer2
0, #buffer3
0, #data_type,
8, #bpp,
rows,
cols,
1)
rc = calldll.call_foreign_function(
accu_io_buffers_to_dib_address,
argfmt,
'l',
calltpl)
rslt = params.read(0, 4)
rslt_tpl = struct.unpack(paramfmt, rslt)
print "buffer_to_dib rc=%d pDIB=%d " % (rc, rslt_tpl[0])
return rslt_tpl[0]
This is a very crude example. You can do much cleverer
things with calldll, but I never learned how.
- Gordon
More information about the Python-list
mailing list