1. Home
  2. EXTERNAL directive

EXTERNAL directive

Declares an external function in a DLL for use by the OWN function.

Options

LIBRARY = text Name of DLL file containing the function

Parameters

FUNCTION = text Name of the function entry point in the DLL
NAME = text Name for the function to be used in the OWN function; default uses the name set in FUNCTION
RESULTS = string token The type of result returned from the function (summary, transformation); default tran
NPARAMETERS = scalar The number of parameters in the function call; default 0
ERRORS = scalar or variate Error codes returned from the function; default * i.e. no error codes
MESSAGES = text Messages for the corresponding error codes

Description

Genstat can execute external functions, stored in DLLs, using the OWN function. You first need to create the DLLs by compiling Fortran or C programs. You can then use EXTERNAL to define the link to Genstat. For example:

EXTERNAL [LIBRARY='CurveFuncs.dll'] FUNCTION='PCNORMAL'; NPAR=0
CALCULATE EX = OWN(X; 'PCNORMAL')
EXTERNAL [LIBRARY='CurveFuncs.dll'] FUNCTION='PEAKRISE'; NPAR=1
CALCULATE P = OWN(X; 'PEAKRISE'; 10)
EXTERNAL [LIBRARY='CurveFuncs.dll'] FUNCTION='HWA';\
RESULTS=summary; NPAR=5
CALCULATE SS = OWN(X; 'HWA'; a; b; g; n; s)

defines three functions in CurveFuncs.dll and then uses these in calculations. The first two return variates with the same length as the first argument X, and the third returns a scalar. The functions have zero, one and five parameters respectively. The parameters in the OWN function follow the data and name arguments, and must be scalars.

The LIBRARY option specifies the name of the file. If the full path to the DLL is not provided, the user add-ins folder is searched first. If the file is not found there, the system add-ins folder is searched. An FI 11 fault is generated if the file is not found.

The FUNCTION parameter gives the name of the entry point in the DLL for the function, and is case insensitive. The entry point must be exported when the program library is compiled. For example, in a C program the function declaration should contain __declspec(dllexport) or its equivalent. If the function entry point is not found in the program library, an FI 12 fault is generated. If you wish to refer to the function in the OWN function by a different name to its entry-point name, you can define that name with the NAME parameter.

The RESULTS parameter indicates what type of result is returned: summary returns a scalar and transformation (default) returns a structure of the same type and size as the first argument.

The NPARAMETERS parameter defines the number of scalar parameters that follow the function name in the OWN function. By default there are none.

The ERRORS, and MESSAGES parameters can be used to set up user-defined fault codes and text for the corresponding error messages for the external functions. If you are using several external functions in a program, you should use different error codes in the different functions, unless the meaning of the code is common to all functions, as the error code/message table is combined over all functions. This allows you to specify just one set of error codes/messages over a set of functions in a library. So, for example, all functions could return a common code 9 if they run out of memory.

The function declaration in C takes the form:
long NAME(double* X, int* NX, double* P, int* NP, double* R, int* NR)

where

X is an array of the input data from the first argument in the OWN function,
NX is the number of elements in X,
P is a pointer to an array of the parameters in OWN function,
NP is the number of parameters,
R is a pointer to the array to hold the results, and
NR is the number of elements in the result array.

NR must be 1 if RESULTS = summary and NX otherwise. The passed array P is NP+1 long, and the last element is the value that Genstat uses to represent a missing value. The function should return zero if it completes successfully, and a positive error code if there is a fault. The error code will be translated to the text in MESSAGES if the error code matches one set up by ERRORS.

For a Fortran program, the declaration would be:

INTEGER FUNCTION NAME(X,NX,P,NP,R,NR)
INTEGER NX,NP,NR
REAL*8 X(*),P(*),R(*)
!DIR$ ATTRIBUTES REFERENCE X,NX,P,NP,R,NR

There are example programs in Fortran (OwnFunction.f90) and C (OwnFunction.c) in the Genstat Source folder. These can be compiled to a DLL library using the appropriate compiler and linker settings. A DLL created from these (OwnFunction.dll) is included in the Genstat system AddIns folder should you want to test this. The function OwnFunction in this DLL calculates the sine of an argument in degrees rather than the usual radians in the standard SIN function. Note, however that these simple examples do not test for missing values in the input data.

Any numeric structure (scalar, variate, matrix, symmetric matrix or diagonal matrix) can be passed to the OWN function and, when RESULTS = transformation, the returned result will be the same type and size of structure (e.g. passing a 3 by 4 matrix will return a 3 by 4 matrix). If you need to pass multiple variates to the function, these could be stacked by the APPEND procedure, and the number of variates could be passed as a parameter. Within the function you would extract the stacked values back into 3 arrays and process these individually. If a single variate is to be returned, you would set just the first NX values in R, and then use its first NX values in Genstat to create the resulting variate. For example:

EXTERNAL [LIBRARY=VarFunc.dll] FUNCTION='XYZFUNC'; NPAR=1
APPEND [V3] X,Y,Z
CALCULATE V = OWN(V3; 'XYZFUNC'; 3)
CALCULATE N = NVALUES(X)
CALCULATE R = V$[!(1...N)]

Option: LIBRARY.
Parameters: FUNCTION, NAME, RESULTS, NPARAMETERS, ERRORS, MESSAGES.

See also

Directives: CALCULATE, PASS, SUSPEND, OWN.
Functions: OWN.
Commands for: Calculations and manipulation.

Updated on February 11, 2022

Was this article helpful?