Linking external functions to Proteus |
In this chapter we will discuss about how to extend the Proteus interpreter (Windows version) by adding new functions written in Visual C++.
Proteus incorporates a communication interface which is illustrated in the example extfunc.prt, whose core is the special directive:
!extern protfunc, filedll, dllfunc, numpar, size
This declaration defines a function from an external DLL; it takes always five parameters, illustrated in the following table:
Parameter Description protfunc name of the function in Proteus filedll filename of the DLL including the function dllfunc name of the function in the DLL (case-sensitive) numpar number of parameters accepted size retained only for compatibility; set to 0 All the strings must be specified literally (no double quotes); e.g.
!extern MessageBox, PROTEXT.DLL, ProteusMessageBox, 3, 0
In the standard distribution, inside the folder Extern, you will find the source code for compiling an example DLL, which allows to call a system function (MessageBox), several functions on Windows clipboard and other functions included in third party libraries, which in turn are dinamically registered by the C++ source code.
To add a new function, open PROTEXT.CPP and add the following definition (change the name as needed):
void APIENTRY MyFunction(ProtVarExt **parms, int numpar, ProtVarExt *retval)
Moreover, edit PROTEXT.DEF and add a line with the name of the exported function and its ordinal number preceded by the character "@".
In the function body, use the following call to access the parameters passed by Proteus:
int GetVar(ProtVarExt *parm, char **cval, long *lval, double *fval, unsigned int *cval_len)
This function returns one or more representations of the requested parameter (only non-NULL pointers are considered). Strings are duplicated and must be freed after being used. The meaning of the different parameters is explained below:
Parameter Description parm parameter passed to the function by Proteus: parms[0] .. parms[numpar - 1] cval address of a character pointer, to which a newly allocated string containing the representation of the requested parameter will be assigned lval address of a long integer, to which the representation of the requested parameter will be assigned fval address of a double precision floating point number, to which the representation of the requested parameter will be assigned cval_len address of an unsigned integer, which will contain the length of the string returned in cval
If the first parameter passed by Proteus is a string, the second is a long integer and the third is a floating point number, the function will be called three times in this way:
char *mystring;
unsigned int len_mystring;
long num_integer;
double num_float;GetVar(parms[0], &mystring, NULL, NULL, &len_mystring);
GetVar(parms[1], NULL, &num_integer, NULL, NULL);
GetVar(parms[2], NULL, NULL, &num_float, NULL);
To discover the type of a variable passed by Proteus, you can use the following macros:
Macro Description PROT_LONG(parms[x]) returns not-zero if the parameter x is a long integer PROT_DOUBLE(parms[x]) returns not-zero if the parameter x is a double precision floating point number PROT_STRING(parms[x]) returns not-zero if the parameter x is a string
When the C++ function ends, it can return a value to Proteus by using the following call:
void SetVar(ProtVarExt *retval, char *cval, long *lval, double *fval, unsigned int *cval_len)
This function sets the value of the variable retval; only the first non-NULL pointer (among cval, lval and fval) is considered. The meaning of the parameters is the following:
Parameter Description retval parameter corresponding to the return value (retval in the examples) cval character pointer, containing the string to be assigned lval long integer pointer, containing the value to be assigned fval pointer to a double precision floating point number, containing the value to be assigned cval_len address of an unsigned integer, containing the length of the string stored in cval; if not specified, the number of bytes copied to retval will be strlen(cval)
The same function can be invoked on the parameters parms[0] .. parms[numpar - 1]; if they are passed by reference, they will get the assigned values upon return.
The function declared in Proteus can be used exactly like any other function.
Start of page | Next topic | Previous topic | Contents | Index |