CALL [INTERFACE4 ]
operand1
[[USING ] operand2
... 128]
|
This document covers the following topics:
For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.
Related Statements: CALL
FILE
| CALL
LOOP
| CALLNAT
|
DEFINE SUBROUTINE
|
ESCAPE
|
FETCH
|
PERFORM
Belongs to Function Group: Invoking Programs and Routines
The CALL
statement is used to call an external
program written in another standard programming language from a
Natural program and then return to the next statement after the
CALL
statement.
The called program may be written in any programming
language which supports a standard CALL
interface. Multiple
CALL
statements to one or more external programs
may be specified.
A CALL
statement may be issued within a program
to be executed under control of a TP monitor, provided that the TP monitor
supports a CALL
interface.
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1 |
C | S | A | yes | no | |||||||||||||||
operand2 |
C | S | A | G | A | U | N | P | I | F | B | D | T | L | C | G | yes | yes |
Syntax Element Description:
Syntax Element | Description |
---|---|
INTERFACE4 |
Interface Usage: The optional
keyword INTERFACE4 specifies the type of the interface that is
used for the call of the external program. See the section
INTERFACE4
below.
|
operand1 |
Program Name:
The name of the program to be called
( |
[USING]
operand2 |
Parameters to be Passed:
The If a group name is used, the group is converted to individual fields; that is, if a user wishes to specify the beginning address of a group, the first field of the group must be specified. |
The condition code of any called program (content of
Register 15 upon return to Natural) may be obtained by using the Natural system
function RET
(Return Code Function).
... RESET #RETURN(B4) CALL 'PROG1' IF RET ('PROG1') > #RETURN WRITE 'ERROR OCCURRED IN PROGRAM1' END-IF ...
Register | Contents |
---|---|
R1 | Address pointer to the parameter address list. |
R2 | Address pointer to the field (parameter) description
list. The field description list contains information on the first 128 fields
passed in the parameter list. Each description is a 4-byte entry containing the
following information:
If field type is N or P:
If field type is X or Y:
All other field types:
|
R3 | Address pointer to list of field lengths. Each length field is a 4-byte entry containing the length of each field passed in the parameter list. In the case of an array, the length is the sum of the individual occurrences' lengths. |
R4 |
Only for type X and Y:
|
R13 | Address of 18-word save area. |
R14 | Return address. |
R15 | Entry address/return code. |
See the section Storage Alignment in the Programming Guide.
A called program may contain a call to Adabas. The called program must not issue an Adabas open or close command. Adabas will open all database files referenced.
If Adabas exclusive (EXU) update mode is to be used, the Natural
profile parameter OPRB
(Database
Open/Close Processing) must be used in order to open all referenced files.
Before you attempt to use EXU update mode, you should consult your Natural
administrator.
If a called program issues Adabas commands that begin or end a transaction, Natural will not be able to recognize the change of the transaction status.
Calls to Adabas must comply with the calling conventions for the Adabas application programming interface (API) for the respective TP monitor or operating system. This applies also if Natural is acting as a server, for example, under z/OS or SMARTS.
The called program may either be directly linked to the Natural
nucleus (that is, the program is specified with the profile parameter
CSTATIC
(Programs Statically Linked to Natural) in the
Natural
parameter module (described in the Operations
documentation), or it may be loaded dynamically the first time it is
called.
If it is to be loaded dynamically, the load module library containing the called program must be concatenated to the Natural load library in the Natural execution JCL or in the appropriate TP-monitor program library. Ask your Natural administrator for additional information.
The example below shows a Natural program which calls the COBOL
program TABSUB
for the purpose of converting a country code into
the corresponding country name. Two parameter fields are passed by the Natural
program to TABSUB
:
the first parameter is the country code, as read from the database;
the second parameter is used to return the corresponding country name.
Calling Natural Program:
** Example 'CALEX1': CALL PROGRAM 'TABSUB' ************************************************************************ DEFINE DATA LOCAL 1 EMPLOY-VIEW VIEW OF EMPLOYEES 2 NAME 2 BIRTH 2 COUNTRY * 1 #COUNTRY (A3) 1 #COUNTRY-NAME (A15) 1 #FIND-FROM (D) 1 #FIND-TO (D) END-DEFINE * MOVE EDITED '19550701' TO #FIND-FROM (EM=YYYYMMDD) MOVE EDITED '19550731' TO #FIND-TO (EM=YYYYMMDD) * FIND EMPLOY-VIEW WITH BIRTH = #FIND-FROM THRU #FIND-TO MOVE COUNTRY TO #COUNTRY /* CALL 'TABSUB' #COUNTRY #COUNTRY-NAME /* DISPLAY NAME BIRTH (EM=YYYY-MM-DD) #COUNTRY-NAME END-FIND END
Called COBOL program TABSUB
:
IDENTIFICATION DIVISION. PROGRAM-ID. TABSUB. REMARKS. THIS PROGRAM PROVIDES THE COUNTRY NAME FOR A GIVEN COUNTRY CODE. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. LINKAGE SECTION. 01 COUNTRY-CODE PIC X(3). 01 COUNTRY-NAME PIC X(15). PROCEDURE DIVISION USING COUNTRY-CODE COUNTRY-NAME. P-CONVERT. MOVE SPACES TO COUNTRY-NAME. IF COUNTRY-CODE = 'BLG' MOVE 'BELGIUM' TO COUNTRY-NAME. IF COUNTRY-CODE = 'DEN' MOVE 'DENMARK' TO COUNTRY-NAME. IF COUNTRY-CODE = 'FRA' MOVE 'FRANCE' TO COUNTRY-NAME. IF COUNTRY-CODE = 'GER' MOVE 'GERMANY' TO COUNTRY-NAME. IF COUNTRY-CODE = 'HOL' MOVE 'HOLLAND' TO COUNTRY-NAME. IF COUNTRY-CODE = 'ITA' MOVE 'ITALY' TO COUNTRY-NAME. IF COUNTRY-CODE = 'SPA' MOVE 'SPAIN' TO COUNTRY-NAME. IF COUNTRY-CODE = 'UK' MOVE 'UNITED KINGDOM' TO COUNTRY-NAME. P-RETURN. GOBACK.
Standard linkage register notation is used in batch mode. Each TP monitor has its own conventions. These conventions must be followed; otherwise, unpredictable results could occur.
The following sections describe conventions that apply for the supported TP monitors.
The called program must reside in the Com-plete online load
library. This allows Com-plete to load the program dynamically. The Com-plete
utility ULIB
may be used to catalog the program.
The called non-Natural subprogram must reside in either a load
module library concatenated to the CICS library or the DFHRPL
library. The subprogram must have a PPT entry in the operating PPT so that CICS
can locate the subprogram and load it.
The CALLRPL
parameter of the
NTCICSP
macro controls where and how the parameter list addresses are passed to the
external subroutine program.
If you wish the parameter values themselves, rather than the
address of their address list, to be passed in a CICS COMMAREA (or Container),
issue the Natural (call options) %P=C
(or
%P=CC
) terminal
command before the call. Alternatively, you can define the call options by
using the PGP
profile
parameter.
When a Natural program calls a non-Natural subprogram under CICS,
the call is accomplished by an EXEC CICS LINK
request.
If you use standard linkage conventions (direct branch using a
BASR instruction) for the call instead, issue the terminal command
%P=S
, or
specify the STDL
property with the
PGP
profile
parameter. In this case, the called subprogram must adhere to standard linkage
conventions with standard register usage.
Issue the %P=SQ
terminal command, or specify the STDLQ
property with the
PGP
profile
parameter if both of the following conditions apply:
The subprogram called using standard linkage conventions is
quasi-reentrant only (but not threadsafe and fully reentrant), that is, it is
defined with the CICS CONCURRENCY(QUASIRENT)
attribute.
Natural is defined with the CICS CONCURRENCY(REQUIRED)
attribute.
As a result, the called subprogram is executed under the CICS QR TCB.
If a program linked with AMODE=24
is called in a
31-bit-mode environment and the threads are allocated above the 16 MB memory
line, a "call by value" will be performed automatically; that is,
the specified parameters which are to be passed to the called program will be
copied below the 16 MB memory line.
CICS itself does not support return codes for a call with CICS
conventions (EXEC CICS LINK
), with the exception of calling C/C++
programs where values passed by the exit()
function or the
return()
statement are saved in the EIBRESP2
field.
However, the Natural CICS Interface supports return codes for the
CALL
statement: When control is returned from the called program,
Natural first checks the EIBRESP2
field for a non-zero return
code.
Then Natural checks whether the first fullword of the COMMAREA has
changed (only if COMMAREA was used for parameter address lists). If it has, its
new content will be taken as the return code. If it has not changed, the first
fullword of the TWA will be checked (only if TWA was used for parameter address
lists) and its new content taken as the return code. If neither of the two
fullwords has changed, the return code will be 0
.
Note:
When parameter values are passed in the COMMAREA (%P=C
),
only the EIBRESP2
field is checked for a return code; that is, for
non-C/C++ programs the return code is always 0
.
To define properties permanently for external programs to be called,
use the profile parameter PGP
. To define
temporary properties for external programs to be called, use the terminal
command %P=
.
A called program written in PL/I requires the following additional procedure:
Since the parameter list is a standard list and is not an
argument list being passed from another PL/I program, the addresses passed do
not point at a LOCATOR DESCRIPTOR
. This problem may be resolved by
defining the parameter fields as arithmetic variables. This causes PL/I to
treat the parameter list as addresses of data instead of addresses of
LOCATOR DESCRIPTOR
control blocks.
The technique suggested for defining the parameter fields is illustrated in the following example:
PLIPROG: PROC(INPUT_PARM_1, INPUT_PARM_2) OPTIONS(MAIN); DECLARE (INPUT_PARM_1, INPUT_PARM_2) FIXED; PTR_PARM_1 = ADDR(INPUT_PARM_1); PTR_PARM_2 = ADDR(INPUT_PARM_2); DECLARE FIRST_PARM PIC '99' BASED (PTR_PARM_1); DECLARE SECOND_PARM CHAR(12) BASED (PTR_PARM_2);
Each parameter in the input list should be treated as a unique element. The number of input parameters should exactly match the number being passed from the Natural program. The input parameters and their attributes must match the Natural definitions or unpredictable results may occur. For additional information on passing parameters in PL/I, see the relevant IBM PL/I documentation.
The following topics are covered below:
** Example 'CALEX2': CALL PROGRAM 'NATPLI' ************************************************************************ DEFINE DATA LOCAL 1 EMPLOY-VIEW VIEW OF EMPLOYEES 2 NAME 2 AREA-CODE 2 REDEFINE AREA-CODE 3 #AC (N1) * 1 #INPUT-NUMBER (N2) 1 #OUTPUT-COMMENT (A15) END-DEFINE * READ EMPLOY-VIEW IN LOGICAL SEQUENCE BY NAME STARTING FROM 'WAGNER' MOVE ' ' TO #OUTPUT-COMMENT MOVE #AC TO #INPUT-NUMBER /* CALL 'NATPLI' #INPUT-NUMBER #OUTPUT-COMMENT /* END-READ * END
Called PL/I program NATPLI
:
NATPLI: PROC(PARM_COUNT, PARM_COMMENT) OPTIONS(MAIN); /* */ /* THIS PROGRAM ACCEPTS AN INPUT NUMBER */ /* AND TRANSLATES IT TO AN OUTPUT CHARACTER */ /* STRING FOR PLACEMENT ON THE FINAL */ /* NATURAL REPORT */ /* */ /* */ DECLARE (PARM_COUNT, PARM_COMMENT) FIXED; DECLARE ADDR BUILTIN; COUNT_PTR = ADDR(PARM_COUNT); COMMENT_PTR = ADDR(PARM_COMMENT); DECLARE INPUT_NUMBER PIC '99' BASED (COUNT_PTR); DECLARE OUTPUT_COMMENT CHAR(15) BASED (COMMENT_PTR); DECLARE COMMENT_TABLE(9) CHAR(15) STATIC INITIAL ('COMMENT1 ', 'COMMENT2 ', 'COMMENT3 ', 'COMMENT4 ', 'COMMENT5 ', 'COMMENT6 ', 'COMMENT7 ', 'COMMENT8 ', 'COMMENT9 '); OUTPUT_COMMENT = COMMENT_TABLE(INPUT_NUMBER); RETURN; END NATPLI;
** Example 'CALEX3': CALL PROGRAM 'CICSP' ************************************************************************ DEFINE DATA LOCAL 1 #MESSAGE (A10) INIT <' '> END-DEFINE * CALL 'CICSP' #MESSAGE DISPLAY #MESSAGE * END
Called PL/I program CICSP:
CICSP: PROCEDURE OPTIONS (MAIN REENTRANT); DCL TWA_ADDRESS BASED(TWA_POINTER); DCL LIST_ADDRESS POINTER; DCL PTR_TO_LIST POINTER BASED(LIST_ADDRESS); DCL PARM_01 POINTER; DCL MESSAGE CHAR(10) BASED(PARM_01); EXEC CICS ADDRESS TWA(TWA_POINTER); MESSAGE='SUCCESS'; EXEC CICS RETURN; END CICSP;
Before using a C program, you need to compile and link it.
Use for instance IBM's C compiler to build the executable module. Since IBM's C compiler produces LE code, the sample is only executable in an LE environment. To execute LE programs, the Natural front-end needs to be installed LE enabled.
If you intend to use any other C compiler, such as Dignus or SASC, you need to build a module which is callable from a non-C environment. Refer to the appropriate compiler documentation for further information.
The include file NATUSER
needs to be included in
the C program.
C programs written for INTERFACE4
can be used on
mainframe systems as well as on UNIX, OpenVMS or Windows systems, whereas C
programs, written for the standard Call Interface, are platform-dependent.
If it is intended to call the C Program via CALL
INTERFACE4
or if a Natural subprogram is called from the C Program,
NATXCAL4
needs to be linked to the executable module. Use one of
the INTERFACE4
Call Back Functions to retrieve the parameter
description and parameter values. The Call Back Functions are described
below.
Use function ncxr_if4_callnat
, to execute a Natural
subprogram from the C program.
Prototype:
int ncxr_if4_callnat ( char *natpgm, int parmnum, struct parameter_description *descr );
Parameter description:
natpgm |
Name of the Natural subprogram to be invoked. | |
parmnum |
Number of parameter fields to be passed to the subprogram. | |
descr |
Address of a struct
parameter_description .
See Operand Structure for INTERFACE4 for a detailed description of this structure. |
|
return |
Return Value: | Information: |
0 |
OK
If an Natural error occurs while the subprogram is
executed, information about this error will be returned in the variable
|
|
-1 |
Illegal parameter number. | |
-2 |
Internal error. |
The following topics are covered below:
** Example 'CALEX4': CALL PROGRAM 'ADD' ************************************************************************ DEFINE DATA LOCAL 1 #OP1 (I4) 1 #OP2 (I4) 1 #SUM (I4) END-DEFINE * CALL 'ADD' #OP1 #OP2 #SUM DISPLAY #SUM * END
Called C program ADD
:
/* ** Example C Program ADD.c */ NATFCT ADD (int *op1, int *op2, int *sum) { *sum = *op1 + *op2; /* add operands */ return 0; /* return successfully */ } /* ADD */
** Example 'CALEX5': CALL PROGRAM 'ADD4' ************************************************************************ DEFINE DATA LOCAL 1 #OP1 (I4) 1 #OP2 (I4) 1 #SUM (I4) END-DEFINE * CALL INTERFACE4 'ADD4' #OP1 #OP2 #SUM DISPLAY #SUM * END
Called C program ADD4
:
NATFCT ADD4 NATARGDEF(numparm, parmhandle, parmdec) { NATTYP_I4 op1, op2, sum; /* local integers */ int i; /* loop counter */ struct parameter_description desc; int rc; /* return code access functions */ /* ** test number of arguments */ if (numparm != 3) return 1; /* ** test types of arguments */ for (i = 0; i < (int) numparm; i++) { rc = ncxr_get_parm_info( i, parmhandle, &desc ); if ( rc ) return rc; if ( desc.format != 'I' || desc.length != sizeof(NATTYP_I4) || desc.dimensions != 0 ) { return 2; /* invalid parameter */ } } /* ** get arguments */ rc = ncxr_get_parm( 0, parmhandle, sizeof op1, (void *)&op1 ); if ( rc ) return rc; rc = ncxr_get_parm( 1, parmhandle, sizeof op2, (void *)&op2 ); if ( rc ) return rc; /* ** perform the addition */ sum = op1 + op2; /* ** move the result back to operand 3 */ rc = ncxr_put_parm( 2, parmhandle, sizeof sum, (void *)&sum ); if ( rc ) return rc; /* ** all ok, return success to the caller */ return 0; } /* ADD4 */
The keyword INTERFACE4
specifies the type of the
interface that is used for the call of the external program. This keyword is
optional. If this keyword is specified, the interface, which is defined as
INTERFACE4
, is used for the call of the external program.
The following table lists the differences between the
CALL
statement used with INTERFACE4
and the one used
without INTERFACE4
:
CALL statement without keyword INTERFACE4 | CALL statement with keyword INTERFACE4 | |
---|---|---|
Number of parameters possible | 128 | 16370 or less |
Maximum data size of one parameter | no restriction | 1 GB |
Retrieve array information | no | yes |
Support of large and dynamic operands | full read access, write without changing size of operand | yes |
Parameter access via API | direct | via API |
The maximum number of parameters is limited by the maximum
size of the generated program (GP) and by the maximum size of a statement.
16370 parameters are possible if the program contains only the
CALL
statement. The maximum number is lower if other statements
are used.
The following topics are covered below:
The interface of the external 3GL program is defined as follows,
when INTERFACE4
is specified with the Natural CALL
statement:
NATFCT functionname (numparm, parmhandle, traditional)
USR_WORD |
numparm; |
16 bit unsigned short value, containing the total
number of transferred operands
(operand2 ).
|
void |
*parmhandle; |
Pointer to the parameter passing structure. |
void |
*traditional; |
Check for interface type (if it is not a
NULL pointer it is the traditional CALL
interface).
|
The operand structure of INTERFACE4
is named
parameter_description
and is defined as follows. The structure is
delivered with the header file natuser.h.
struct
parameter_description |
|||
void * |
address |
Address of the parameter
data, not aligned, realloc() and free() are not
allowed.
|
|
int |
format |
Field data format:
NCXR_TYPE_ALPHA , etc. (natuser.h).
|
|
int |
length |
Length (before decimal point, if applicable). | |
int |
precision |
Length after decimal point (if applicable). | |
int |
byte_length |
Length of field in bytes
int dimension number of dimensions (0 to
IF4_MAX_DIM ).
|
|
int |
dimensions |
Number of dimensions
(0 to IF4_MAX_DIM ).
|
|
int |
length_all |
Total data length of array in bytes. | |
int |
flags |
Several flag bits
combined by bitwise OR operation, meaning:
|
|
IF4_FLG_PROTECTED :
|
The parameter is write protected. | ||
IF4_FLG_DYNAMIC :
|
The parameter is a dynamic variable. | ||
IF4_FLG_NOT_CONTIGUOUS :
|
The array elements are not contiguous (have spaces between them). | ||
IF4_FLG_AIV :
|
The parameter is an application-independent variable. | ||
IF4_FLG_DYNVAR :
|
The parameter is a dynamic variable. | ||
IF4_FLG_XARRAY :
|
The parameter is an X-array. | ||
IF4_FLG_LBVAR_0 :
|
The lower bound of dimension 0 is variable. | ||
IF4_FLG_UBVAR_0 :
|
The upper bound of dimension 0 is variable. | ||
IF4_FLG_LBVAR_1 :
|
The lower bound of dimension 1 is variable. | ||
IF4_FLG_UBVAR_1 :
|
The upper bound of dimension 1 is variable. | ||
IF4_FLG_LBVAR_2 :
|
The lower bound of dimension 2 is variable. | ||
IF4_FLG_UBVAR_2 :
|
The upper bound of dimension 2 is variable. | ||
int |
occurrences[IF4_MAX_DIM] |
Array occurrences in each dimension. | |
int |
indexfactors[IF4_MAX_DIM] |
Array index factors for each dimension. | |
void * |
dynp |
Reserved for internal use. | |
void * |
pops |
Reserved for internal use. |
The address element is null for arrays of dynamic variables and for X-arrays. In these cases, the array data cannot be accessed as a whole, but must be accessed through the parameter access functions described below.
For arrays with fixed bounds of variables with fixed length, the array contents can be accessed directly using the address element. In these cases the address of an array element (i,j,k) is computed as follows (especially if the array elements are not contiguous):
elementaddress = address + i * indexfactors[0] + j * indexfactors[1] + k * indexfactors[2]
If the array has less than 3 dimensions, leave out the last terms.
A set of functions is available to be used for the access of the parameters. The process flow is as follows:
The 3GL program is called via the CALL
statement
with the INTERFACE4
option, and the parameters are passed to the
3GL program as described above.
The 3GL program can now use the exported functions of Natural, to retrieve either the parameter data itself, or information about the parameter, such as format, length, array information, etc.
The exported functions can also be used to pass back parameter data.
There are also functions to create and initialize a new parameter set in order to call arbitrary subprograms from a 3GL program. With this technique a parameter access is guaranteed to avoid memory overwrites done by the 3GL program. (Natural's data is safe: memory overwrites within the 3GL program's data are still possible).
The following topics are covered below:
This function is used by the 3GL program to receive all
necessary information from any parameter. This information is returned in the
struct parameter_description
, which is documented
above.
Prototype:
int ncxr_get_parm_info ( int parmnum, void *parmhandle, struct parameter_description *descr );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter of the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the internal parameter structure | |
descr |
Address of a
struct parameter_description |
|
return |
Return Value: | Information: |
0 |
OK | |
-1 |
Illegal parameter number. | |
-2
|
Internal error. | |
-7 |
Interface version conflict. |
This function is used by the 3GL program to get the data from any parameter.
Natural identifies the parameter by the given parameter number and writes the parameter data to the given buffer address with the given buffer size.
If the parameter data is longer than the given buffer size,
Natural will truncate the data to the given length. The external 3GL program
can make use of the function ncxr_get_parm_info
, to request the
length of the parameter data.
There are two functions to get parameter data:
ncxr_get_parm
gets the whole parameter (even if the parameter is
an array), whereas ncxr_get_parm_array
gets the specified array
element.
If no memory of the indicated size is allocated for "buffer" by the 3GL program (dynamically or statically), results of the operation are unpredictable. Natural will only check for a null pointer.
If data gets truncated for variables of the type I2/I4/F4/F8 (buffer length not equal to the total parameter length), the results depend on the machine type (little endian/big endian). In some applications, the user exit must be programmed to use no static data to make recursion possible.
Prototypes:
int ncxr_get_parm( int parmnum, void *parmhandle, int buffer_length, void *buffer ) int ncxr_get_parm_array( int parmnum, void *parmhandle, int buffer_length, void *buffer, int *indexes )
This function is identical to ncxr_get_parm
, except
that the indexes for each dimension can be specified. The indexes for unused
dimensions should be specified as 0
.
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter of the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the internal parameter structure | |
buffer_length |
Length of the buffer, where the requested data has to be written to | |
buffer |
Address of buffer, where the requested data has to be written to. This buffer should be aligned to allow easy access to I2/I4/F4/F8 variables. | |
indexes |
Array with index information | |
return |
Return Value: | Information: |
< 0 |
Error during retrieval of the information: | |
-1 |
Illegal parameter number. | |
-2 |
Internal error. | |
-3 |
Data has been truncated. | |
-4 |
Data is not an array. | |
-7 |
Interface version conflict. | |
-100 |
Index for dimension 0 is out of range. | |
-101 |
Index for dimension 1 is out of range. | |
-102 |
Index for dimension 2 is out of range. | |
0 |
Successful operation. | |
> 0 |
Successful operation, but the data was only this number of bytes long (buffer was longer than the data). |
These functions are used by the 3GL program to write back the data to any parameter. Natural identifies the parameter by the given parameter number and writes the parameter data from the given buffer address with the given buffer size to the parameter data. If the parameter data is shorter than the given buffer size, the data will be truncated to the parameters data length, that is, the rest of the buffer will be ignored. If the parameter data is longer than the given buffer size, the data will be copied only to the given buffer length, the rest of the parameter stays untouched. This applies to arrays in the same way. For dynamic variables as parameters, the parameter is resized to the given buffer length.
If data gets truncated for variables of the type I2/I4/F4/F8 (buffer length not equal to the total parameter length), the results depend on the machine type (little endian/big endian). In some applications, the user exit must be programmed to use no static data to make recursion possible.
Prototypes:
int ncxr_put_parm ( int parmnum, void *parmhandle, int buffer_length, void *buffer ); int ncxr_put_parm_array ( int parmnum, void *parmhandle, int buffer_length, void *buffer, int *indexes );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter of the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the internal parameter structure. | |
buffer_length |
Length of the data to be copied back to the address of buffer, where the data comes from. | |
indexes |
Index information | |
return |
||
Return Value: | Information: | |
< 0 |
Error during copying of the information: | |
-1 |
Illegal parameter number. | |
-2 |
Internal error. | |
-3 |
Too much data has been given. The copy back was done with parameter length. | |
-4 |
Parameter is not an array. | |
-5 |
Parameter is protected (constant or
AD=O ).
|
|
-6 |
Dynamic variable could not be resized due to an "out of memory" condition. | |
-7 |
Interface version conflict. | |
-13 |
The given buffer includes an incomplete Unicode character. | |
-100 |
Index for dimension 0 is out of range. | |
-101 |
Index for dimension 1 is out of range. | |
-102 |
Index for dimension 2 is out of range. | |
0 |
Successful operation. | |
> 0 |
Successful operation., but the parameter was this number of bytes long (length of parameter greater than given length). |
If a 3GL program wants to call a Natural subprogram, it needs to
build a parameter set that corresponds to the parameters the subprogram
expects. The function ncxr_create_parm
is used to create a set of
parameters to be passed with a call to ncxr_if_callnat
. The set of
parameters created is represented by an opaque parameter handle, like the
parameter set that is passed to the 3GL program with the CALL
INTERFACE4
statement. Thus, the newly created parameter set can be
manipulated with functions ncxr_put_parm*
and
ncxr_get_parm*
as described above.
The newly created parameter set is not yet initialized after
having called the function ncxr_create_parm
. An individual
parameter is initialized to a specific data type by a set of
ncxr_parm_init*
functions described below. The functions
ncxr_put_parm*
and ncxr_get_parm*
are then used to
access the contents of each individual parameter. After the caller has finished
with the parameter set, they must delete the parameter handle. Thus, a typical
sequence in creating and using a set of parameters for a subprogram to be
called through ncxr_if4_callnat
will be:
ncxr_create_parm ncxr_init_ parm* ncxr_init_ parm* ... ncxr_put_ parm* ncxr_put_ parm* ... ncxr_get_parm_info* ncxr_get_parm_info* ... ncxr_if4_callnat ... ncxr_get_parm_info* ncxr_get_parm_info* ... ncxr_get_ parm* ncxr_get_ parm* ... ncxr_delete_parm
The function ncxr_create_parm
is used to create a
set of parameters to be passed with a call to ncxr_if_callnat
.
Prototype:
int ncxr_create_parm( int parmnum, void** pparmhandle )
Parameter Description:
parmnum |
Number of parameters to be created. | |
pparmhandle |
Pointer to the created parameter handle. | |
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Illegal parameter count. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
0 |
Successful operation. |
The function ncxr_delete_parm
is used to delete a
set of parameters that was created with ncxr_create_parm
.
Prototype:
int ncxr_delete_parm( void* parmhandle )
Parameter Description:
parmhandle |
Pointer to the parameter handle to be deleted. | |
return |
Return Value: | Information: |
< 0 |
Error: | |
-2 |
Internal error. | |
0 |
Successful operation. |
Prototype:
int ncxr_init_parm_s( int parmnum, void *parmhandle, char format, int length, int precision, int flags );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter in the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the parameter handle. | |
format |
Format of the parameter. | |
length |
Length of the parameter. | |
precision |
Precision of the parameter. | |
flags |
IF4_FLG_PROTECTED |
|
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Invalid parameter number. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
-8 |
Invalid format. | |
-9 |
Invalid length or precision. | |
0 |
Successful operation. |
Prototype:
int ncxr_init_parm_sa( int parmnum, void *parmhandle, char format, int length, int precision, int dim, int *occ, int flags );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter in the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the parameter handle. | |
format |
Format of the parameter. | |
length |
Length of the parameter. | |
precision |
Precision of the parameter. | |
dim |
Dimension of the array. | |
occ |
Number of occurrences per dimension. | |
flags |
A combination of the
flags
|
|
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Invalid parameter number. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
-8 |
Invalid format. | |
-9 |
Invalid length or precision. | |
-10 |
Invalid dimension count. | |
-11 |
Invalid combination of variable bounds. | |
0 |
Successful operation. |
Prototype:
int ncxr_init_parm_d( int parmnum, void *parmhandle, char format, int flags );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter in the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the parameter handle. | |
format |
Format of the parameter. | |
flags |
IF4_FLG_PROTECTED |
|
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Invalid parameter number. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
-8 |
Invalid format. | |
0 |
Successful operation. |
Prototype:
int ncxr_init_parm_da( int parmnum, void *parmhandle, char format, int dim, int *occ, int flags );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter in the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the parameter handle. | |
format |
Format of the parameter. | |
dim |
Dimension of the array. | |
occ |
Number of occurrences per dimension. | |
flags |
A combination of the
flags
|
|
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Invalid parameter number. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
-8 |
Invalid format. | |
-10 |
Invalid dimension count. | |
-11 |
Invalid combination of variable bounds. | |
0 |
Successful operation. |
Prototype:
int ncxr_resize_parm_array( int parmnum, void *parmhandle, int *occ );
Parameter Description:
parmnum |
Ordinal number of the
parameter. This identifies the parameter in the passed parameter list. Range:
0 ... numparm-1 .
|
|
parmhandle |
Pointer to the parameter handle. | |
occ |
New number of occurrences per dimension. | |
return |
Return Value: | Information: |
< 0 |
Error: | |
-1 |
Invalid parameter number. | |
-2 |
Internal error. | |
-6 |
Out of memory condition. | |
-12 |
Operand is not resizable (in one of the specified dimensions). | |
0 |
Successful operation. |
All function prototypes are declared in the file
natuser.h
.