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, a 4-byte long entry for each variable of type A or B that exceeds the size of 32767 bytes. |
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 one of the load libraries of the the
DFHRPL
library concatenation of the CICS JCL. The subprogram must have a
processing program table (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. This does not apply to LE
subprograms. For information on how Natural supports IBM Language Environment (LE)
subprograms, see section LE Subprograms in the Natural
Operations documentation.
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. The CICS-supplied stub routines (for example,
DFHELII
) do not need to be linked to the called subprogram if no EXEC
CICS commands are executed.
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 PPT
attribute CONCURRENCY(QUASIRENT)
.
Natural is defined with the CICS PPT attribute
CONCURRENCY(REQUIRED)
.
As a result, the called subprogram is executed under the CICS QR TCB.
For more information about this topic, see section Threadsafe Considerations in the Natural TP Monitor Interfaces documentation.
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 Linux 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 a 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 (output only). | |
int |
dimensions |
Number of dimensions (0 to
IF4_MAX_DIM ).
|
|
int |
length_all |
Total data length of array in bytes (output only). | |
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_callnat_handle
.
Prototype:
int ncxr_callnat_handle(int subname, void *parmhandle)
Parameter description:
subname |
Name of subprogram that is called | |
parmhandle |
Parameter set handle | |
return |
Return Value: | Information: |
< 0 | Error | |
0 | Successful operation |
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_callnat_handle
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_callnat_handle ... 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_callnat_handle
.
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
.