External Procedures
An EES Procedure is a block of code written by the user that returns one or more outputs for a given set of inputs. Internal Procedures are written directly within EES. A remarkable feature of EES is that the user can also add (and later remove) external Procedures written in C, Pascal, and FORTRAN. The external Functions and Procedures are used in exactly the same manner as internal Functions and internal Procedures.
External Procedures are written as dynamic link libraries (DLLs) under the Windows operating system. There are two formats for external Procedures, which exchange information with the external routines in different ways. The .FDL format passes inputs and outputs in arrays containing 8 byte real numbers (doubles). The .DLP format passes inputs and outputs as linked list. EES identifies the format by the file name extension which must be .FDL or .DLP. External Procedures written in FORTRAN 77 must have a .FDL file name extension since linked lists are not possible. Newer versions of FORTRAN, as well as C, C++ and Pascal procedures can use either format.
When EES is started, it examines the files in the USERLIB\ (or USERLIB64 for the 64-bit license) subdirectory and subdirectories within these directories. Any files having a .DLP or .FDL (or .DLP64, .FDL64) file name extension are assumed to be external Procedures and they are automatically loaded unless directed otherwise by the Library Manager. The Procedure name used in the EES equations is the file name (without the extension). An external Procedure can also be manually loaded using the Load Library command in the File menu or by use of the $INCLUDE directive. It is possible to load multiple EES Procedures and Functions in one .DLL file as explained in the Multiple External Routines section.
.DLP Format
A skeleton listing of a compiled procedure in .DLP format is shown below. This listing is written in Delphi but the same calling sequence is used in C++. Example code for DELPHI and C++ are provided below.
library XTRNPROC;
{$N+}
type
CharString = array[0..255] of char;
ParamRecPtr = ^ParamRec;
ParamRec = record { defines structure of the linked list of inputs }
Value: double;
next: ParamRecPtr;
end;
procedure ProcName (var S:charstring; var Mode:integer; Inputs, Outputs:ParamRecPtr): export; stdCall;
begin
....
{Set values of Outputs in linked list here; Outputs must be extended precision }
....
end;
exports ProcName;
begin
end.
The major concern is the Procedure header. To be recognized by EES, the Procedure name, called ProcName in the above example, must be the same as the file name. The procedure statement has four arguments.
S is a 255 character ansi C string with 1 byte per character. The actual string length may be less than 255 characters. It is terminated with a chr(0), following the normal C string conventions. S can be used both to send text information from EES and to return text information from the external procedure. The text information sent from EES to the function appears within single quotes as the first argument in the procedure call statement, as in the following example.
Call ProcName('optional text', Input1, Input2 : Output1, Output2, Output3)
Arguments are separated by a list separator which is the comma in the U.S. system and the semicolon in the European system.
Starting with version 9.513, it is not necessary to have the external Procedure evaluate all of the outputs. For example, if only Output2 is needed, the Call statement can be written as
Call ProcName('optional text', Input1, Input2 : , Output2, )
Note that the list separators still indicate that there three outputs but all of the outputs do not need to be provided. Computational time will be reduced when the number of outputs is reduced.
The text information is optional. If it appears in the Call statement, as above, then S will be set to this text without the quotes. Otherwise, S will be set to a null string. The input and output variables of external Procedures are always 8-byte doubles regardless of the Complex Numbers setting. Note that Array Range Notation (e.g., X[1..5] can be used as shorthand in the Call statement.
Mode is an integer set by EES as an input to the external routine with the following purpose:
Mode=-1: EES is requesting that the external Procedure return in S an example of the EES call format.
Mode=-2: EES is requesting that the external Procedure return in S a string containing the units of each of the inputs, separated by a list separator (comma or semicolon).
Mode=-3: EES is requesting that the external Procedure return in S a string containing the units of each of the output, separated by a list separator (comma or semicolon).
Mode=>0 The procedure should calculate and return the output values.
Note that EES will provide unit checking if the external procedure provides the strings of inputs and outputs requested with Modes=-2 and -3. Otherwise it will skip unit checking for this equation.
Inputs is a pointer to the head of a linked list of input values supplied by EES. Each input consists of a value (8-byte double) and a pointer to the next input, as indicated by the ParamRec structure. The procedure may have one or more inputs. The next field of the last input will be a null pointer (nil). The Procedure should count the inputs to be sure that the number supplied is as expected and issue an error message in S if this is not the case.
Outputs is a pointer to the head of a linked list of output values calculated by the external Procedures using the supplied input values. Each output consists of a value (8-byte double) and a pointer to the next output, as indicated by the ParamRec structure. The procedure may have one or more outputs. The next field of the last outputs will be a null pointer (nil).
S is returned from the external Procedure as the null string and Mode should be set to 0 under normal circumstances . If an error or warning is encountered in the external function, S should be set to an appropriate error message and Mode should be set to a positive value. If the string is not null and MODE>=0, EES will then terminate calculations and display this error message. If MODE<0, then EES will assume that string S provides a warning message, which it will display and continue calculations.
Click here to view an example of an EES .DLP external procedure written in Delphi 5
Click here to view an example of an EES .DLP external procedure written in C++
A method to register external functions and procedures is implemented in EES versions 10.011 and newer. Before calling the Procedure the first time, EES will call it with Mode=-1 and with the character string S set to '['+EESIDNo+']', e.g., [1234]. EESIDNo is the EES registration number that appears on the EES start-up screen. The external procedure can ignore this information or it can internally set to flag if this EES license is not intended to use the external procedure.
.FDL Format
The .FDL format differs from the .DLP format in that it uses arrays to transfer the inputs and outputs between EES and the external routine, rather than linked lists. An .FDL external routine can be written in any compiled language, including FORTRAN, C++, and DELPHI. The format for all languages is illustrated by the following FORTRAN subroutine fragments.
32-bit .FDL library using the Digital Visual FORTRAN 5.0 compiler
SUBROUTINE MYPROC(S,MODE,NINPUTS,INPUTS,NOUTPUTS,OUTPUTS)
!DEC$ATTRIBUTES ALIAS:'MYPROC' :: MYPROC
!DEC$ATTRIBUTES DLLEXPORT :: MYPROC
INTEGER(4) MODE, NINPUTS, NOUTPUTS
REAL(8) INPUTS(50), OUTPUTS(50)
CHARACTER(255) S
…
OUTPUTS(1)=…
…
RETURN
END
S is a 255 character string (CHARACTER(255) in FORTRAN) that can be used both to send text information to the procedure and to return text information from the procedure. The text information sent from EES must appear within single quotes as the first argument in the procedure Call statement, as in the following example.
Call MYSUB('optional text', Input1, Input2 : Output1, Output2, Output3)
If only Output3 is to be evaluated by the Procedure, the Call statement can appear in versions 9.513 or newer as:
Call MYSUB('optional text', Input1, Input2 : {Output1}, {Output2}, Output3)
The text information is optional. If it appears in the Call statement, as above, then S will be set to this text (without the quotes). Otherwise, S will be set to the null string.
The external Procedure is expected to provide an example of the calling sequence of the procedure in string S when MODE=-1. S is also used to return an error message if necessary in which case the external procedure must set MODE to a value greater than 0. The error message will terminate calculations. A warning message (which does not terminate calculations) can be presented by setting MODE to a value less than 0 and copying the warning message to string S. In normal operation, MODE=0 and S need not be defined.
NINPUTS and NOUTPUTS are the number of inputs and outputs provided by EES. The routine should check to see if these agree with the expected number of inputs and outputs. INPUTS is an array of REAL*8. (REAL*8 is a double in C++ and Delphi.) Calculated results are placed in the OUTPUTS REAL*8 array. There above example shows the INPUTS and OUTPUTS array to be dimensioned for 50 elements, but this limit is flexible. The current implementation in EES can pass up to 410 variables to an external procedure.
Click here to view a .FDL external procedure in FORTRAN using Microsoft Visual Studio
Click here to view a .FDL external procedure in C++
HELP for External Routines
Information concerning external procedures can be obtained in an identical manner to built-in functions with the Function Info command in the Options menu. The Function Info dialog has a Function Info button which, when used, provides help explaining the use of the selected function. When the user clicks the Function Info button, EES will look for a file with the name of the compiled routine and a .PDF, .CHM, .TXT or .HTM file name extension. The .TXT file is an ASCII text file. The .HTM file should contain HTML code readable by a browser. This help file will be displayed if the file is found in the directory in which the external library file resides; otherwise a message will appear which states that help is not available for this item.
If an ASCII file is provided, it should be formatted so that each paragraph ends with a carriage return. Long lines that do not fit within the Help window will be broken and word-wrapped as needed. Blank lines and spaces can be used to make the text more clear.
Note that .PDF files, Windows .CHM files (such as the you are now reading) and .HTM files allow figures and formatting options and so it is a better way of providing help than a .TXT file. The Windows .CHM and .HTM files can be composed using any Help generating program. .HTM files can also be written in Microsoft Word.