$ZF (ObjectScript)
Synopsis
$ZF("function_name",args)
Arguments
Argument | Description |
---|---|
function_name | The name of the function you want to call. |
args | Optional — A set of argument values passed to the function. |
Description
The various forms of the $ZF function allow you to invoke non-ObjectScript programs (such as shell or operating system commands) or functions from ObjectScript code. You can define interfaces or links to functions written in other languages into InterSystems IRIS and call them from ObjectScript code using $ZF.
Other $ZF Functions
$ZF can also be used to:
-
Spawn a child process to execute a program or command: $ZF(-100).
-
Load a Dynamic Link Library (DLL) then execute functions from that library: $ZF(-3), $ZF(-4), $ZF(-5), and $ZF(-6).
These implementations of $ZF take a negative number as the first argument. They are described in their own reference pages.
Arguments
function_name
The name of the function you want to call enclosed in quotation marks, or a negative number.
args
The args arguments are in the form: arg1, arg2, arg3, ...argn. The arguments can consist of such items as descriptions of how arguments are passed and the entry point to the C function you are calling.
Calling UNIX® System Services with $ZF
InterSystems IRIS supports error checking functions for use with UNIX® system calls from $ZF. These calls allow you to check for asynchronous events and to set an alarm handler in $ZF. By using these UNIX® functions you can distinguish between real errors, <CTRL-C> interrupts, and calls that should be restarted.
The function declarations are included in iris-cdzf.h and are described in the following table:
Declaration | Purpose | Notes |
---|---|---|
int sigrtclr(); | Clears retry flag. | Should be called once before using sigrtchk() |
int dzfalarm(); | Establishes new SIGALRM handler. | On entry to $ZF, the previous handler is automatically saved. On exit, it is restored automatically. A user program should not alter the handling of any other signal. |
int sigrtchk(); | Checks for asynchronous events. |
Should be called whenever one of the following system calls fails: open(), close(), read(), write(), ioctl(), pause(), any call that fails when the process receives a signal. It returns a code indicating the action the user should take: -1 = Not a signal. Check for I/O error. See contents of errno variable. 0 = Other signal. Restart operation from point at which it was interrupted. 1 = SIGINT/. Exit from $ZF with a SIGTERM "return 0." The System traps these signals appropriately. |
In a typical $ZF function used to control some device, you would code something like this:
IF ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
; Set some flags
; Call zferror
; return 0;
}
The open system call can fail if the process receives a signal. Usually this situation is not an error and the operation should be restarted. Depending on the signal, however, you might take other actions. So, to take account of all the possibilities, consider using the following C code:
sigrtclr();
WHILE (TRUE) {
IF (sigrtchk() == 1) { return 1 or 0; }
IF ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
switch (sigrtchk()) {
case -1:
/* This is probably a real device error */
; Set some flags
Call zferror
return 0;
case 0:
/* A innocuous signal was received. Restart. */
; continue;
case 1:
/* Someone is trying to terminate your job. */
Do cleanup work
return 1 or 0;
}
}
ELSE { break; }
/* Code to handle the normal situation: */
/* open() system call succeeded */
Remember you must not set any signal handler except through dzfalarm().
Translating Strings between Encoding Systems
InterSystems IRIS supports input-output translation via a $ZF argument type, t (or T), which can be specified in the following formats:
Argument | Purpose |
---|---|
t | Specifies the current process I/O translation object. |
t// | Specifies the default process I/O translation table name. |
t/name/ | Specifies a particular I/O translation table name. |
$ZF conveys the translated string to the external procedure via a counted-byte string placed in the following C structure:
typedef struct zarray {
unsigned short len;
unsigned char data[1]; /* 1 is a dummy value */
} *ZARRAYP;
This is also the structure used for the b (or B) argument type.
The following $ZF sample function performs a round trip conversion:
#include iris-cdzf.h
extern int trantest();
ZFBEGIN
ZFENTRY("TRANTEST","t/SJIS/ T/SJIS/",trantest)
ZFEND
int trantest(inbuf,outbuf);
ZARRAYP inbuf; /* Buffer containing string that was converted from
internal InterSystems IRIS encoding to SJIS encoding before it
was passed to this function */
ZARRAYP outbuf; /* Buffer containing string in SJIS encoding that will
be converted back to internal InterSystems IRIS encoding before
it is passed back into the InterSystems IRIS environment */
{
int i;
/* Copy data one byte at a time from the input argument buffer
to the output argument buffer */
for (i = 0; i < inbuf->len; i++)
outbuf->data[i] = inbuf->data[i];
/* Set number of bytes of data in the output argument buffer */
outbuf->len = inbuf->len;
return 0; /* Return success */
}
Conceptually speaking, data flows to and from a $ZF external procedure, as if the external procedure were a device. The output component of an I/O translation is used for data that is passed to an external procedure because the data is “leaving” the InterSystems IRIS environment. The input component of an I/O translation is used for data that is received from an external procedure because the data is “entering” the InterSystems IRIS environment.
If the output component of an I/O translation is undefined and your application attempts to pass anything but the null string using that I/O translation, InterSystems IRIS returns an error, because it does not know how to translate the data.
If the input component of an I/O translation is undefined and an argument of type string associates that I/O translation with a $ZF output argument, InterSystems IRIS returns an error, because an output argument with an undefined translation is purposeless.
Zero-Terminated and Counted Unicode Strings
The $ZF function supports argument types for zero-terminated Unicode strings and counted Unicode strings.
The argument types for zero-terminated Unicode strings and counted Unicode strings have the following codes:
Argument | Purpose |
---|---|
w | Pointer to a zero-terminated Unicode character string. |
s | Pointer to a counted Unicode character string. |
For both argument types, the C data type of the Unicode character is an unsigned short. A pointer to a zero-terminated Unicode string is declared as follows:
unsigned short *p;
A pointer to a counted Unicode string is declared as a pointer to the following C structure:
typedef struct zwarray {
unsigned short len;
unsigned short data[1]; /* 1 is a dummy value */
} *ZWARRAYP;
For example:
ZWARRAYP *p;
The len field contains the length of the Unicode character array.
The data field contains the characters in the counted Unicode string. The maximum size of a Unicode string is the maximum $ZF string size, which is an updateable configuration parameter that defaults to 32767.
Each Unicode character is two bytes long. This is important to consider when declaring Unicode strings as output arguments, because InterSystems IRIS reserves space for the longest string that may be passed back. When using the default string size, the total memory consumption for a single Unicode string argument is calculated as follows:
32767 maximum characters * 2 bytes per character = 65534 total bytes.
This is close to the default maximum memory area allocated for all $ZF arguments, which is 67584. This maximum $ZF heap area is also an updateable configuration parameter.
Error Messages
When the $ZF heap area is exhausted, $ZF issues an <OUT OF $ZF HEAP SPACE> error. When the $ZF String Stack is exhausted, $ZF issues a <STRINGSTACK> error. When $ZF is unable to allocate a buddyblock, it issues a <STORE> error.