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