TECHNICAL BULLETIN #117 - Rev 1.00 (7/30/96)
==============================================================================
TITLE : DLLs and Windows ASPECT: PASCAL Language Specifications
PRODUCT : Procomm Plus 4.x, 3.x
==============================================================================
Procomm Plus implements a powerful scripting language called the Windows
ASPECT Script Language (ASPECT). One of ASPECT's strengths is the ability to
call functions embedded in Dynamic Link Libraries (DLLs) written and compiled
outside of ASPECT. This paper focuses on writing DLLs for ASPECT using Turbo
Pascal for Windows (TPW) from Borland International, Inc.
ASPECT TO DLL PARAMETER SEQUENCE
ASPECT generates a standard parameter block for every DLL call that it makes.
This standard parameter block has five parameters, listed in order below.
When writing a DLL to be called from ASPECT, every exported function that is
to be accessible from within ASPECT should declare these parameters:
1. [HWnd] - a handle to the Procomm Plus main window.
2. [THandle] - a handle to the instance of Procomm Plus that made the DLL
call.
3. [pointer to array[0..9] of pointer] - a pointer to an array of pointers to
the data elements listed as parameters on the ASPECT script line that
called the DLL function.
4. [pointer to array[0..9] of byte] - a pointer to an array of bytes. Byte N
of this array describes the type of element N stored in the array of data
elements (i.e. parameter 3). The range of values in this array follows
this scheme:
Byte Value Meaning
---------------------------------------------
0 nth element is an ASPECT string
1 nth element is an ASPECT integer
2 nth element is an ASPECT long
3 nth element is an ASPECT float
5. [int] - an integer containing the count of parameters provided on the
ASPECT script line calling the DLL function
AN EXAMPLE DLL
Here is the code for a DLL with a function that generates a random number.
Under a PASCAL style, stack-based parameter passing scheme, a variable number
of parameters is not normally possible; however, ASPECT provides an
array-based parameter passing scheme as described by the parameter block
above. To demonstrate the ability to pass a variable number of parameters, the
DLL function listed below makes certain assumptions about the provided
parameters based on the number of parameters that are available:
1. If two parameters are passed to the DLL function, the first parameter holds
a number for seeding the random-number generator and the second parameter
will hold the return value (i.e. the random number).
2. If one parameter is passed to the DLL function, the DLL function should
seed the random number generator using the Randomize function from the TPW
System Unit and the parameter will hold the return value (i.e. the random
number). Sample DLL: RANDINT.PAS library RandInt; uses WinTypes;
const
IntegerType = 1;
LongType = 2;
MaxWord: Word = 65535;
type
pdatptrary = ^tdatptrary;
tdatptrary = array[0..9] of pointer;
ptypptrary = ^ttypptrary;
ttypptrary = array[0..9] of byte;
function RandomInt(PWWnd: HWnd; PWInst: THandle; PData: pdatptrary;
PType: ptypptrary; argcnt: integer): BOOL; export;
begin
if (argcnt < 1) then
begin {at least one arg?}
RandomInt := FALSE; {if not, return failure to Aspect}
exit;
end;
if (argcnt > 1) then
begin
if ((PType^[0] <> LongType) or (PType^[1] <> IntegerType)) then
begin
RandomInt := FALSE; {for two args, 1=long, 2=int}
exit; {if not, return failure to Aspect}
end;
RandSeed := PLongint(PData^[0])^; {seed generator}
PWord(PData^[1])^ := Random(MaxWord); {get the random number}
end
else
begin
if (PType^[0] <> IntegerType) then
begin
RandomInt := False; {for one arg, 1=int}
exit; {if not, return failure to Aspect}
end;
Randomize; {seed generator with time}
PWord(PData^[0])^ := Random(MaxWord); {get the random number}
end;
RandomInt := True; {return success to aspect}
end;
exports
RandomInt index 1;
begin
end.
Sample ASPECT script: RANDINT.WAS:
;ASPECT script demonstrating RANDINT.DLL
integer hdll, rnum
long seed = 1060665
proc cleanup
dllfree hdll
exit
endproc
proc main
string DLLPATH = "C:\PROWIN\ASPECT\RANDINT.DLL" ;path to the DLL
when userexit call cleanup ;point to cleanup routine
dllload DLLPATH hdll ;load the DLL
if (failure)
usermsg "dllload failed"
exit
endif
;generate a random number letting the DLL use system time as seed
dllcall hdll "RandomInt" rNum
if (failure)
usermsg "RandomInt call with system time seed failed"
cleanup()
else
usermsg "RandomInt with system time seed returned %u" rNum
endif
;generate a random number with the our seed
dllcall hdll "RandomInt" seed rNum
if (failure)
usermsg "RandomInt call with our seed failed"
cleanup()
else
usermsg "RandomInt with our seed returned %u" rNum
endif
cleanup()
endproc
==============================================================================
To ensure that you have the latest version of this document, compare its
revision number to that of the same document on any of our support sites.
This technical bulletin may be copied and distributed freely as long as it
is distributed in its entirety and it is not distributed for profit.
Copyright (c) 1998 Quarterdeck All rights reserved.
==============================================================================
|