Tech Bulletin 78: DLLs and ASPECT: C Language Specifications

Procomm Plus -- ASPECT
Revision: 1.10 (5/13/96)
Author: Mike Robertson


TECHNICAL BULLETIN #78 - Rev 1.10 (9/03/96)

==============================================================================
TITLE   : DLLs and ASPECT: C Language Specifications
PRODUCT : Procomm Plus 4.x, 3.x
==============================================================================

Procomm Plus for Windows 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 document focuses on writing DLLs for
ASPECT in the C language.

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.  [HANDLE] - a handle to the instance of Procomm Plus that made the DLL
    call.

3.  [void far * far *] - a far array of far pointers to the data elements
    listed as parameters on the ASPECT script line that called the DLL
    function.

4.  [LPBYTE] - a far array of bytes.  Byte N of this array describes the type
    of element N stored in the array of data elements (e.g., 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 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 GetCurrentTime() function from
    the Windows API and the parameter will hold the return value (i.e. the
    random number).


SAMPLE DLL: RANDINT.C

#include <windows.h>
#include <stdlib.h>

#define IntegerType 1

int FAR PASCAL LibMain( HANDLE, WORD, WORD, LPSTR );
int FAR PASCAL RandomInt( HWND, HANDLE, void far * far *, LPBYTE, int );
int FAR PASCAL WEP( int );

HANDLE hInst;

int FAR PASCAL LibMain( HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
  LPSTR lpszCmdLine )
{
  if (cbHeapSize)
    UnlockData(0);    /* make the data segment moveable */
  hInst = hInstance;
  return(TRUE);
}

int FAR PASCAL RandomInt( HWND PWWnd, HANDLE PWInst,
  void far * far *vdatptr, LPBYTE vtypeptr, int argcnt )
{
  if ( argcnt < 1 )                     /* at least one argument? */
    return( FALSE );                    /* if not, return FAILURE */
  if ( vtypeptr[0] != IntegerType )     /* is first arg an integer? */
    return( FALSE );                    /* if not, return FAILURE */
  if ( argcnt > 1 ) {                   /* more arguments? */
    if ( vtypeptr[1] != IntegerType )   /* is second arg an integer? */
      return( FALSE );                  /* if not, return FAILURE */
    srand( *(int far *)vdatptr[0] );    /* seed the generator with arg */
    *(int far *)vdatptr[1] = rand();    /* get a random number */
  }
  else {
    srand( (unsigned)GetCurrentTime() );/* seed the generator with time */
    *(int far *)vdatptr[0] = rand();    /* get a random number */
  }
  return( TRUE );                       /* return SUCCESS to ASPECT */
}

int FAR PASCAL WEP( int bSystemExit )
{
  return(TRUE);
}



SAMPLE PROJECT DEFINITION FILE: RANDINT.DEF

       LIBRARY RandInt
       CODE MOVEABLE DISCARDABLE
       DATA SINGLE MOVEABLE
       HEAPSIZE 2048
       EXPORTS
         WEP        @1
         RandomInt  @2



SAMPLE ASPECT SCRIPT: RANDINT.WAS

;ASPECT script demonstrating RANDINT.DLL
integer hdll, rNum
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 %d" rNum
   endif

   ;generate a random number with the seed 65
   dllcall hdll "RandomInt" 65 rNum
   if (failure)
      usermsg "RandomInt call with seed 65 failed"
      cleanup()
   else
      usermsg "RandomInt with seed 65 returned %d" 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.
==============================================================================