Calling a Windows dll (with pointers parameters) with calldll

pyxis@iol.it pyxis at iol.it
Sun Feb 16 15:50:26 EST 2003


Here is the code I used to call a Windows dll like that """void FAR PASCAL hllapi(int FAR *, char FAR *, int FAR *, int FAR *)""" with calldll (http://www.nightmare.com/software.html).

For me, without documentation, calling a windows dll who needs pointers was a nightmare.

And then I'd like to show you the code (may this 'll be useful to you).

PS
Yes, I know there is ctypes (http://starship.python.net/crew/theller/ctypes.html) but with ctypes it's too easy to do ;-)


# PROGRAM NAME : HLLAPI interface - calldll version
# Author: Stefano Spinucci
# Written: 2002/02/16
# DESCRIPTION
# This program interface the 3270 HLLAPI library of an Italian 3270 emulator using 
# the calldll library (from Sam Rushing http://www.nightmare.com/software.html)
# I've found very useful also edll.py from http://pages.ccapcable.com/lac/undergroundPython.html
# The calling scheme for the function is :
# void FAR PASCAL hllapi(int FAR *, char FAR *, int FAR *, int FAR *);

# ------------------------------------------------------------------------------------------------
# Function defining : 
# - myPrintLong : given a membuf with a long inside, print the long
# - myPrintString : given a membuf with a string inside, print the string
# - mySetLong : given a membuf with a long inside len (4), set his value with the long passed
# ------------------------------------------------------------------------------------------------

def myPrintLong(vVar):
	#Print the long (first way)
	a= struct.unpack('I', vVar.read())[0]
	print a

	#Print the long (second way)
	print calldll.read_long(vVar.address())

def myPrintString(vVar):
	#Print the string (first way)
	a = vVar.read()
	print a[:len(a)-1]
	print len(a)

	#Print the string (second way)
	a = calldll.read_string(vVar.address())
	print a
	print len(a)

def mySetLong(vMemBuf, vValueToSet):
	string_packed = struct.pack("L",vValueToSet) # packed as unsigned long
	vMemBuf.write(string_packed)

def mySetString(vMemBuf, vValueToSet):
	data_len = len(vValueToSet) 
	pack_format = str(data_len+1)+"s" # add one for \0 at the end. 
	string_packed = struct.pack(pack_format, vValueToSet) # pack() will add \0 for us
	vMemBuf.write(string_packed)

# ------------------------------------------------------------------------------------------------
# Import the required library
# ------------------------------------------------------------------------------------------------

#Import the calldll module
import calldll
#Import the struct module (a standard python module)
import struct

# ------------------------------------------------------------------------------------------------
# Get the handle of the dll and the address of the function
# ------------------------------------------------------------------------------------------------

#Get the handle of the Dll
handle = calldll.load_library ('C:\Tee3270\Ehllap32')

#Get the address of the function
address = calldll.get_proc_address (handle, 'HLLAPI')

# ------------------------------------------------------------------------------------------------
# Initialization
# ------------------------------------------------------------------------------------------------
# vFunction, vTextLen and vResult are defined as a membuf with lenght = 4, because 4 is the lenght 
# of an unsigned long packed with struct.pack("L", NumberToPack)
vFunction = calldll.membuf(4)
vTextLen = calldll.membuf(4)
vResult = calldll.membuf(4)
# vFunction is defined as a membuf with lenght = 1921 because the dll needs a buffer of 
# 1920 char + 1 for \0 at the end
vText = calldll.membuf(1921)

# ------------------------------------------------------------------------------------------------
# Function calling
# ------------------------------------------------------------------------------------------------

# Vars setting
#1
mySetLong(vFunction, 1)
#2
string_value_to_write = 'A'
mySetString(vText, string_value_to_write)
#3
mySetLong(vTextLen, len(string_value_to_write))
#4
mySetLong(vResult, 1)

#Call the function
calldll.call_foreign_function (
			address,
			'llll',
			'l',
			(vFunction.address(), vText.address(), vTextLen.address(), vResult.address())
			)


myPrintLong(vResult)
myPrintString(vText)

# ------------------------------------------------------------------------------------------------
# Dll unloading
# ------------------------------------------------------------------------------------------------

#Unload the dll
calldll.free_library (handle)







More information about the Python-list mailing list