ILE C/C++ Programmer's Guide

Passing Parameters from ILE C++ to a Different High-Level Language

To share data between programs (or between procedures), you need to pass parameters which both programs can use to the called program or procedure. In C++, you use the linkage specification to tell the compiler which parameter passing convention to use on the external call.


C++ language only
When passing parameters from C++ to a different high-level language (HLL) consider:

Using Different Linkage Specifications

Table 20 shows the effect of using different linkage types when passing parameters:

Table 20. Effects of Various Linkage Specifications

Linkage Name Mangled Parameter Passing Parameter Widening Comments
"C++" Yes C++ No This is the default.
"C" No C++ Yes Used to call a function (procedure) written in ILE C.
"C nowiden" No C++ No Used to call a function (procedure) written in ILE C.
"OS" No OS Yes Used to call an external program written in any OPM/EPM/ILE language.
"OS nowiden" No OS No Used to call an external program written in any OPM/EPM/ILE language.
"RPG" No OS No Used to call a procedure written in ILE RPG. Parameters with address types (pointer or reference) are passed by value directly. All other parameters are passed by value indirectly.
"COBOL" No OS No Used to call a procedure written in ILE COBOL. Parameters with address types (pointer or reference) are passed by value directly. All other parameters are passed by value indirectly.
"CL" No OS No Used to call a procedure written in ILE CL. Parameters with address types (pointer or reference) are passed by value directly. All other parameters are passed by value indirectly.
"ILE" No OS Yes Used to call a procedure written in an ILE language. Identical to RPG, COBOL, and CL specifications. If the particular language in which the function was written is unknown to the programmer, use this linkage. If you have C code that uses the #pragma argument directive and you plan to port this code to C++ then use the extern "ILE" linkage specification.
"ILE nowiden" No OS No Used to call a procedure written in an ILE language.
"VREF" No OS Yes Used to call a procedure written in an ILE language. Parameters are passed by value indirectly.
"VREF nowiden" No OS No Used to call a procedure written in an ILE language. Parameters are passed by value indirectly.

Specifying that a Function Has ILE Linkage

The extern keyword followed by the string literals "RPG", "COBOL", or "CL" are used to specify that the function has "ILE" linkage. These string literals perform the same function as the #pragma argument directive in ILE C. The "VREF" linkage also performs the same as the VREF parameter on the #pragma argument directive.

Note:
For more information on the #pragma argument directive, see WebSphere Development Studio: ILE C/C++ Compiler Reference.

Specifying ILE, CL, COBOL, and RPG Linkage

Specifying an ILE, CL, COBOL, or RPG linkage for a function tells the compiler:

Specifying VREF Linkage

Specifying a VREF linkage is identical to specifying an ILE linkage except that pointer parameters are stored in a temporary variable and the address of the temporary variable is passed as the actual argument.

Specifying that a Function Has External (OS) Linkage

The extern specifier followed by the string-literal "OS" or the string-literal "OS nowiden" is used to declare external programs. These programs may then be called in the same way as a regular function.

When an OS linkage function is called from a C++ program, the compiler generates code and performs the following tasks in sequence:

  1. If extern "OS" is used, then the parameters and return value are widened.

    If extern "OS nowiden" is used, then the parameters and return value passed between programs are not widened.

  2. Parameters that are passed by value are copied to temporary variables and the addresses of the temporary variables are passed to the called program.

    If a temporary variable is created for a structure, the temporary variable has the same structure and information as the struct parameter passed.

  3. Parameters that were passed by reference are still passed by reference.
  4. Arrays and pointers are passed by reference.
  5. If the argument you are passing is an array name or a pointer, then the argument is passed directly, and a temporary variable is not created. The data referenced by the array or pointer can be changed by the called program.
  6. The function name is not mangled.

The program name that the C++ dynamic program calls must be in uppercase. You can use the #pragma map directive to map an internal identifier longer than 10 characters to an OS/400-compliant object name (10 characters or less) in your program. See Renaming Programs and Procedures.

The return code for the dynamic program call can be retrieved by declaring the program to return an integer:

extern "OS" int PGMNAME(void);

The value returned on the call is the return code for the dynamic program call. If the program being called is a C++ program, this return code can be accessed using the _LANGUAGE_RETURN_CODE macro defined in the header file <milib.h>. A C++ program returns four bytes in the _LANGUAGE_RETURN_CODE. If the program being called is an EPM or OPM program, this return code can be accessed using the iSeries Retrieve Job Attributes (RTVJOBA) command.

When a function is called from an OS linkage function pointer, the compiler generates the same code sequence it does when calling an OS linkage function.

Non-pointer arguments are passed by value reference, and changes made to the variables in the called program are not reflected in the calling C++ program.

Specifying that a Function Has C Linkage

Specifying C linkage for a function tells the compiler:

The extern keyword followed by the string-literal "C" or the string-literal "C nowiden" is used to specify that the function is declared to have "C" linkage instead of "C++" linkage.

Using Different Linkage Specifications (C++ Only)


C++ language only
When using the extern "literal" statement, consider that:

Using Default Parameter Passing Styles

To pass parameters between ILE C/C++ and other ILE languages, especially ILE C, ILE RPG, or ILE COBOL, you must ensure that the other procedure is set up to accept data by reference.

ILE C++ uses the same calling mechanisms for calling any ILE HLL program or procedure: extern linkage specification.

ILE C++ passes and receives parameters using three passing methods:

By value, directly
The value of the data object is placed directly into the argument list.

By value, indirectly
The value of the data object is copied to a temporary location. The address of the copy, a pointer, is placed into the argument list.

By reference
A pointer to the data object is placed into the argument list. Changes made by the called procedure to the argument are reflected in the calling procedure.

Other ILE languages may have different methods of passing data. See Table 21.

Table 21. Default Argument Passing Style for ILE Programs

ILE HLL Pass Argument Receive Argument
ILE C by value, directly or by reference by value, directly or by reference
ILE C++ by value, directly or by value, indirectly or by reference by value, directly or by reference
ILE COBOL by reference or by value, indirectly by reference or by value, indirectly
ILE RPG by reference by reference
ILE CL by reference by reference

Table 22 shows the common parameter passing methods for the ILE procedures.

Table 22. Default Argument Passing Style for ILE Procedures

ILE HLL Pass Argument Receive Argument
ILE C by value, directly by value, directly
ILE C++ by value, directly or by value, indirectly or by reference by value, directly or by reference
ILE COBOL by reference or by value, indirectly by reference
ILE RPG by reference by reference
ILE CL by reference by reference

Using Operational Descriptors to Pass Parameters of Unknown Data Type

To pass a parameter to a procedure even though the data type is not precisely known to the called procedure you can use operational descriptors. Operational descriptors provide descriptive information to the called procedure regarding the form of the argument. This information allows the procedure to properly interpret the passed parameter. Use operational descriptors only when they are expected by the called procedure.

Note:
For more information on operational descriptors, see:

The C++ compiler supports operational descriptors for describing null-terminated strings. A character string in C++ is defined by: char string_name[n], char * string_name, or string-literal.

C++ defines a string as a contiguous sequence of characters terminated by and including the first null character. In another language, a string may be defined as consisting of a length specifier and a character sequence. When passing a string from a C++ function to a function written in another language, an operational descriptor can be provided with the argument to allow the called function to determine the length and type of the string being passed.

To use operational descriptors, you specify a #pragma descriptor directive in your source to identify functions whose arguments have operational descriptors. Operational descriptors are then built by the calling procedure and passed as hidden arguments to the called procedure. For the syntax, see WebSphere Development Studio: ILE C/C++ Compiler Reference.

The following examples illustrates the use of operational descriptors in ILE C/C++. They show:

Example: Calling a Function with Operational Descriptors

The following figure shows an ILE C program that calls func1(). When the function func1() is called, the compiler generates operational descriptors for the three arguments that are specified on the call.

Figure 235. ILE C Source to Call a Function with Operational Descriptors




#include "oper_desc.h"
...
main()
{
char a[5] = {'s', 't', 'u', 'v', '\0'};
char *c;
c = "EFGH";
...
func1(a, "ABCD", c);
}


[ Top of Page | Previous Page | Next Page | Table of Contents ]