The User Exit command allows you to call a routine (that is performed outside of ECMap) from inside a map, pass parameters to the routine, and receive parameters back from it.
When the User Exit command is executed on a Windows PC, the RTP calls userex32.dll. This .dll has one main function to which the RTP can pass parameters and which can return parameters to the RTP.
When the User Exit command is executed on a Unix machine, the RTP calls a shared library (userex32.lib).
Enter the following information on the Rule Command window for the User Exit window and it is passed as parameters to the .dll or shared library:
User Routine Name – the name of the routine that is passed to the .dll or shared library.
The User Routine Input identifies whether data is passed to the .dll or shared library, and if so, the location from which it is passed. Choose from:
Memory Variable – displays next to the Rule Command window. Drag a memory variable and drop it on the User Routine Input text box.
Record/Field – displays next to the Rule Command window. Navigate down through a record to reveal the fields. Drag a field and drop it on the User Routine Input text box.
Record Only – displays next to the Rule Command window. Drag a record and drop it on the User Routine Input text box.
None – No input is passed to the routine. None is entered in the User Routine Input text box.
The User Routine Output identifies whether data is returned from the .dll or shared library, and if so, the location to which it is passed. Choose from:
Memory Variable – displays next to the Rule Command window. Drag a memory variable and drop it on the User Routine Output text box.
Record/Field – displays next to the Rule Command window. Navigate down through a record to reveal the fields. Drag a field and drop it on the User Routine Output text box.
Record Only – displays next to the Rule Command window. Drag a record and drop it on the User Routine Output text box.
None – No input is returned from the routine. Enter None in the User Routine Output text box.
The Status Variable is a memory variable that contains a user-generated value returned by the .dll or shared library. The generated value must be a 2-digit numeric value. (If you enter non-numeric data, the program converts it to “00”.) The value in this status variable can be used to test for special conditions.
The User Language identifies the language in which the user exit routine is written. Choose from:
C
COBOL
You must start out writing C code in the .dll. From the .dll, you can call any other executable using a “System” call or a “CreateProcess” call. With Unix, the user exit is a shared library. ECMap provides you with a stub, written in C - for this shared library. Once you have entered this stub, you can write code to call other code that may be written in COBOL or other languages.
In addition to entering values on the Rule Command window, users must modify the userexit.c file provided by ECMap and recompile it to create a new userex32.dll. or userex32.lib. The userexit.c file included with ECMap is printed below.
Add the code for your routine where it is specified (in bold) at the end of the file and then recompile the file to produce a new userex32.dll or shared library. When the RTP is run, the values you entered on the Rule Command window are passed in as parameters, the routine is executed, and any values you specified to be passed back are returned.
Since there can be only one user exit .dll or shared library, you must imbed the logic and the resulting actions within the code you enter in the userexit.c file, to perform different actions from the User Exit command.
#ifndef UNIX #include <windows.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef UNIX #include <unistd.h> #endif #ifndef UNIX extern "C" __declspec (dllexport) void WINAPI USEREXIT(char *, short, char *, char *, char *); #endif /*----------------------------------------------------* UserExit - Windows DLL and Unix shared library.* This file and userdll.c and userexit.def are used for userexit.dll. * This file alone is used for UNIX shared library userexit.sl *----------------------------------------------------- * USEREXIT function. * Parameters: * char * cpuExitName - pointer to dynamically * allocated storage which contains the routine name. * This pointer should not be written to. This value * can * be used to determine what action should be done * by USEREXIT() function. short sLanguage - will * contain a 1 for Cobol or a 2 for 'C' language. * char * cpRegBuf - pointer to input buffer which has * been loaded with the value of a Memvar, Record Field * or Record Buffer. For 16 bit program the maximum * record buffer length is 3200 characters. For 32 bit * program the maximum record buffer length is 10000 . * characters * char * cpRetBuf - pointer to output buffer, where the * routine output of Memvar, Record Field or Record * Buffer should be placed. * * Note cpRegBuf and cpRetBuf have been set to point to * the same large buffer. Empty input cpRegBuf before * writing to output cpRetBuf. * char * cpStatus - pointer to dynamically allocated * storage which has been space filled and null * terminated to actual length of memvar of status * memvar. The user exit routine should be careful not * to store more information in the field than it can . * hold parameter returns: cpRetbuf, and cpStatus. * return value: none *----------------------------------------------------*/ #ifndef UNIX __declspec (dllexport) void WINAPI USEREXIT(char *cpUExitName, short sLanguage, char *cpRegBuf, char *cpRetBuf, char *cpStatus) #else void #ifndef NO_PROTO USEREXIT(char *cpUExitName, short sLanguage, char *cpRegBuf, char *cpRetBuf, char *cpStatus) #else USEREXIT(cpUExitName, sLanguage, cpRegBuf, cpRetBuf, cpStatus) char *cpUExitName; short sLanguage; char *cpRegBuf, char *cpRetBuf, char *cpStatus; #endif #endif { #ifndef UNIX MessageBeep(-1); /* ring bell - user will add code here */ #else write(0,"\007", 1); /* ring bell - user will add code here */ #endif }