|
With our latest set of PTFs (which includes V3R2, V3R7 and subsequent releases), Net.Data is providing a new language environment, Direct Call (DTW_DIRECTCALL), which enables calling System i programs (e.g. C, RPG, CL, Cobol, etc.) and the ability to pass parameters
to and receive values
from the program that is being called.
The major benefits of this support is the easy integration of existing programs with Net.Data and the performance improvement over the System language environment.
The Direct Call feature of Net.Data makes it very easy to call other System i compiled programs from Net.Data. Prior to this enhancement, you needed to call a stored procedure to pass parameters and receive parameters, or use the System language environment to call a program and pass values in environment variables (using the System i system APIs
QtmhGetEnv and
QtmhPutEnv).
Function definition to call a program
Net.Data uses a new function type to contain the program invocation. The DTW_DIRECTCALL function type defines a function name (used in the Net.Data macro), the parameter list, and the return value (if any) from the called program. The code inside the function contains a single %EXEC statement that identifies the program to be called.
An example of the function definition with parameters and the called program is:
%function(dtw_directcall) CheckDate(IN CHAR(8) pFormat,
IN CHAR(10) pValue,
INOUT CHAR pReturn) {
%exec { CHECKDATE.PGM %}
%}
In your Net.Data macro, you can invoke the function like this (for example):
@CheckDate(DATE_FORMAT,DATE_VALUE,DATE_OK)
You may have noticed that the parameter names on the function definition (pFormat, pValue and pReturn) are not referred to in the function definition itself. The parameter names are used as placeholders for the parameter values that you pass to or receive from the called program. Even though the names are not used, you are required to specify names. Although it is possible to use simple non-descriptive names like p1, p2 and p3, you may want to consider using more descriptive names so that you can easily match the parameters in the Net.Data function definition with the parameters used in the called program.
You can define a maximum of 50 parameters to pass to the called program.
Defining the Parameter Direction
You need to indicate the direction of the parameter. The direction is specified in terms of the called program:
- IN -- the parameter value is passed to the called program. Any changes made to the parameter value in the called program are not visible to the Net.Data macro upon return from the called program.
- OUT -- the parameter value is received from the called program.
- INOUT -- the parameter value is passed from Net.Data to the called program, and received back into the Net.Data macro from the called program.
Parameter Data Types
The following data types may be specified for parameters. You need to be aware that some of the parameter data types that are supported by the Direct Call LE may not be usable in the High Level Language (HLL) program you are calling.
| Data type |
Comments |
CHAR(n)
CHAR
CHARACTER(n)
CHARACTER
|
If n is specified, it must be greater than zero. If not specified, the string is assumed to be one character long. Because all strings passed from the Direct Call LE are null-terminated, the LE allocates n+1 bytes. |
| VARCHAR(n) |
A variable length character string, where n is greater than zero and less than or equal to 32740. The string is null-terminated and the LE allocates n+2+1 bytes (2 bytes to store the string length, 1 byte for the null-terminator). The first two bytes of two bytes of the string contain the string length (binary value). If the parameter is defined as OUT (output only), the string length is set to zero before the variable is passed to the called program. |
INTEGER
INT
|
A signed binary integer, 4 bytes long. |
| SMALLINT |
A signed binary integer, 2 bytes long. |
| REAL(p,s) |
Single precision floating point number. The precision p must be greater than 0 and less than 25. The precision (p) and scale (s) are only used when converting data to a displayable format (for example, to a string). |
| FLOAT(p,s) |
Single precision or double precision floating point number. For single precision, p must be greater than 0 and less than 25. For double precision, p must be greater than 24 and less than 54. The precision (p) and scale (s) are only used when converting data to a displayable format (for example, to a string) |
DOUBLEPRECISION(p,s)
DOUBLE(p,s)
|
Double precision floating point number. The precision p must be greater than 0 and less than 53. The precision (p) and scale (s) are only used when converting data to a displayable format (for example, to a string). |
| NUMERIC(p,s) |
A zoned decimal number, with precision p and scale s. The value of p must be greater than 0 and less than 32. |
DECIMAL(p,s)
DEC(p,s)
|
A packed decimal number, with precision p and scale s. The value of p must be greater than 0 and less than 32. |
| DTWTABLE |
A special data type used to pass a Net.Data table to the called program. The Direct Call LE passes a pointer to the table, which can be manipulated using the Net.Data LE interface table functions. |
Note that parameters that are defined to be numeric may include the currency symbol and 3-digit seperators. The Direct Call LE will remove the currency symbol and 3-digit seperators when converting a numeric variable from string form to its internal form before passing the variable to the program. The currency symbol, decimal format, and 3-digit seperator characters are retrieved from the process attributes of the process that Net.Data is running in.
Calling the Program
The actual call to the program is done using an %EXEC statement inside the function. There are two formats you can use to call the program:
%EXEC { /qsys.lib/mylib.lib/myprogram.pgm %}
%EXEC { myprogram.pgm %}
You can always use the first format and specify the complete Integrated File System (IFS) type path to the program. Note that you can only call programs in the System i library file system (compiled System i system objects). You cannot, for example, invoke a PC .EXE program that is stored in the IFS.
To use the second format (program name only), you need to specify the library where the program is located using the EXEC_PATH directive in the Net.Data INI file (the INI file must reside in the library where your copy of the DB2WWW program is located, and must have a member named DB2WWW that contains your Net.Data directives).
For example, you can use the following EXEC_PATH directive to locate the program in the %EXEC statement:
EXEC_PATH /qsys.lib/mylib.lib
(
Note: you can include multiple libraries in the EXEC_PATH, separated with a semicolon.)
Working with Null-terminated String Parameters
Because Net.Data passes string values to your program using a null terminator character (value x'00'), you will need to write code to handle the string (unless you are using ILE-C or C++, which expect null terminated strings).
For example, if you define the parameter field as CHAR(10) but pass a string value that is only five bytes long, Net.Data puts the null terminator after the fifth byte. Passing the value "12345" as a string in a CHAR(10) field yields:
x'F1F2F3F4F500........'
where the bytes following the null terminator are undefined (you cannot assume that the bytes are null or blank).
Because the string is null terminated and contains uninitialized bytes after the null terminator, you cannot simply use the string in an RPG or COBOL program. For example, if you use the string in a comparison operation, the operation will not yield valid results, since the program expects the string to not contain the null terminator and to be blank padded at the end.
You can use string handling functions within your program to extract the string value by using the ILE-RPG string handling functions to extract a string passed from a Net.Data macro to an ILE-RPG program.
Common Parameter Passing Errors
Because you cannot detect errors in your parameter list until run-time, you need to be especially aware of the following parameter passing errors:
- Parameter Mismatch Errors -- You must match the number and order of the parameters in the macro and in the called program.
- Data Type Errors -- The data type specified in the Net.Data macro must match the data type used in the called program. If your HLL does not support one of the valid Net.Data data types, you must not use that data type to pass values to the called program.
- Length Errors -- The parameter lengths must match the lengths specified in the called program.
Returning Values From Programs
Some HLL programs (such as ILE-C and C++) can return an integer value as a result of the program call (the value is typically used to indicate the success or failure of operations in the called program). You can retrieve the return value in your Net.Data macro by specifying the RETURNS keyword:
%function(dtw_directcall) CheckDate(IN CHAR(8) pFormat)
Returns(returnValue) {
.
.
.
%}
|