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.