There are two types of Rexx external functions:
Routines written in Rexx
Routines written in other Windows-supported languages
External functions written in Rexx do not need to be registered. These functions are found by a disk search for a Rexx procedure file that matches the function name.
An external function can reside in the same module (executable or DLL) as an application, or in a separate dynamic-link library. RexxRegisterFunctionExe registers external functions within an application module. External functions registered with RexxRegisterFunctionExe are available only to Rexx programs called from the registering application.
The RexxRegisterFunctionDll interface registers external functions that reside in a dynamic-link library. Any Rexx program can access such an external function after it is registered. It can also be registered directly from a Rexx program using the Rexx RXFUNCADD built-in function.
The following is a sample external function definition:
ULONG APIENTRY SysLoadFuncs( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */
where:
is the address of an ASCII function name used to call the external function.
is the number of elements in the Argv array. Argv contains Argc RXSTRINGs.
is an array of null-terminated RXSTRINGs for the function arguments.
is the name of the currently defined external Rexx data queue.
is the address of an RXSTRING for the returned value. Retstr is a character string function or subroutine return value. When a Rexx program calls an external function with the Rexx CALL instruction, Retstr is assigned to the special Rexx variable RESULT. When the Rexx program calls an external function with a function call, Retstr is used directly within the Rexx expression.
The Rexx interpreter provides a default 256-byte RXSTRING in Retstr. A longer RXSTRING can be allocated with GlobalAlloc(size) if the returned string is longer than 256 bytes. The Rexx interpreter releases Retstr with GlobalFree(ptr) when the external function completes.
is an integer return code from the function. When the external function returns 0, the function completed successfully. Retstr contains the return value. When the external function returns a nonzero return code, the Rexx interpreter raises Rexx error 40, "Incorrect call to routine". The Retstr value is ignored.
If the external function does not have a return value, the function must set Retstr to an empty RXSTRING (null strptr). When an external function called as a function does not return a value, the interpreter raises error 44, "Function or message did not return data". When an external function called with the Rexx CALL instruction does not return a value, the Rexx interpreter drops (unassigns) the special variable RESULT.
RexxRegisterFunctionExe external functions are local to the registering process. Another process can call the RexxRegisterFunctionExe to make these functions local to this process. RexxRegisterFunctionDll functions, however, are available to all processes. The function names cannot be duplicated.
ULONG APIENTRY SysMkDir( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */ { ULONG rc; /* Return code of function */ if (Argc != 1) /* must be 1 argument */ return 40; /* incorrect call if not */ /* make the directory */ rc = !CreateDirectory(Argv[0].strptr, NULL); sprintf(Retstr->strptr, "%d", rc); /* result: <> 0 failed */ /* set proper string length */ Retstr->strlength = strlen(Retstr->strptr); return 0; /* successful completion */ }
The following sections explain the functions for registering and using external functions.
RexxRegisterFunctionDll registers an external function that resides in a dynamic-link library routine.
retc = RexxRegisterFunctionDll(FuncName, ModuleName, EntryPoint);
is the address of an external function name. The function name must not exceed 1024 characters.
is the address of an ASCII dynamic-link library name. ModuleName is the DLL file containing the external function routine.
is the address of an ASCII dynamic-link procedure name. EntryPoint is the name of the exported external function routine within ModuleName.
EntryPoint can only be a 32-bit routine.
External functions that reside in a dynamic-link library routine must be exported. You can do this by specifying a module-definition (.DEF) file that lists the external functions in the EXPORT section. You must export these functions with both the mixed-case and the uppercase name. For example:
EXPORTS SYSMKDIR = SysMkDir
A Rexx procedure can register dynamic-link library-external functions with the RXFUNCADD built-in function. For example:
/* register function SysLoadFuncs */ /* in dynamic link library RexxUTIL*/ Call RxFuncAdd "SysLoadFuncs", "RexxUTIL", "SysLoadFuncs" Call SysLoadFuncs /* call to load other functions */
RXFUNCADD registers the external function SysLoadFuncs as routine SysLoadFuncs in the RexxUTIL dynamic-link library. SysLoadFuncs registers additional functions in RexxUTIL.DLL with RexxRegisterFunctionDll. See the SysLoadFuncs routine below for a function registration example.
static PSZ RxFncTable[] = /* function package list */ { "SysCls", "SysCurpos", "SysCurState", "SysDriveInfo", } ULONG SysLoadFuncs( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */ { INT entries; /* Number of entries */ INT j; /* counter */ Retstr->strlength = 0; /* set null string return */ if (Argc > 0) /* check arguments */ return 40; /* too many, raise an error */ /* get count of arguments */ entries = sizeof(RxFncTable)/sizeof(PSZ); /* register each function in */ for (j = 0; j < entries; j++) { /* the table */ RexxRegisterFunctionDll(RxFncTable[j], "RexxUTIL", RxFncTable[j]); } return 0; /* successful completion */ }
RexxRegisterFunctionExe registers an external function that resides within the application code.
retc = RexxRegisterFunctionExe(FuncName, EntryPoint);
is the address of an external function name. The function name must not exceed 1024 characters.
is the address of the external function entry point within the executable application file. Functions registered with RexxRegisterFunctionExe are local to the current process. Rexx procedures in the same process as the RexxRegisterFunctionExe issuer can call local external functions.
RexxDeregisterFunction deregisters an external function.
retc = RexxDeregisterFunction(FuncName);
is the address of an external function name to be deregistered.
RexxQueryFunction queries the existence of a registered external function.
retc = RexxQueryFunction(FuncName);
is the address of an external function name to be queried.
RexxQueryFunction returns RXFUNC_OK only if the requested function is available to the current process. If not, the RexxQueryFunction searches the external RexxRegisterFunctionDll function list.