Create a physical file to contain an audit trail for the ILE C program.
Create an ILE CL program that passes the parameters item name, price, quantity, and user ID to an ILE C program.
Create a CL command prompt to enter data for item name, price, and quantity. The command passes the data to the ILE CL program which in turn calls an ILE C program.
Create an ILE COBOL module that completes the tax calculation and formats the total cost.
Create an ILE RPG module that writes the audit trail for the application.
Create a service program that exports a data item.
Create a service program that exports an RPG procedure.
Create one program with a main() function that receives incoming arguments from a CL program. The program calls an ILE COBOL procedure to complete the tax calculation and format the total cost, and calls an ILE RPG procedure to write audit records.
To create a physical file T1520DD2 using the source shown in Figure 1, enter:
Figure 1. T1520DD2 — Source to Create Physical Files
R T1520DD2R
USER 10 COLHDG('User')
ITEM 20 COLHDG('Item name')
PRICE 10S 2 COLHDG('Unit price')
QTY 4S COLHDG('Number of items')
TXRATE 2S 2 COLHDG('Current tax rate')
TOTAL 21 COLHDG('Total cost')
DATE 6 COLHDG('Transaction date')
K USER
This file contains the audit trail for the ILE C program T1520ICB.
To create a CL program T1520CL3 that the source shown in Figure 2, enter:
Figure 2. T1520CL3 — ILE CL Source to Pass Variables to an ILE C Program
/* ILE version of T1520CL2 */
PGM PARM(&ITEMIN &PRICE &QUANTITY)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&ITEMIN) TYPE(*CHAR) LEN(20)
DCL VAR(&ITEMOUT) TYPE(*CHAR) LEN(21)
DCL VAR(&PRICE) TYPE(*DEC) LEN(10 2)
DCL VAR(&QUANTITY) TYPE(*DEC) LEN(2 0)
DCL VAR(&NULL) TYPE(*CHAR) LEN(1) VALUE(X'00')
/* ADD NULL TERMINATOR FOR THE ILE C PROGRAM */
CHGVAR VAR(&ITEMOUT) VALUE(&ITEMIN *TCAT &NULL)
/* GET THE USERID FOR THE AUDIT FILE */
RTVJOBA USER(&USER)
/* ENSURE AUDIT RECORDS WRITTEN TO CORRECT AUDIT FILE MEMBER */
OVRDBF FILE(T1520DD2) TOFILE(*LIBL/T1520DD2) +
MBR(T1520DD2) OVRSCOPE(*CALLLVL) SHARE(*NO)
CALL PGM(T1520ICB) PARM(&ITEMOUT &PRICE &QUANTITY +
&USER)
DLTOVR FILE(*ALL)
ENDPGM
Note: To pass parameters to an ILE program when you run it, use the PARM option of the CL Call (CALL) command.
This program passes the CL variables item name, price, quantity, and user ID by reference to an ILE C program T1520ICB. The Retrieve Job Attributes (RTVJOBA) command obtains the user ID for the audit trail. Arguments are passed by reference. They can be changed by the receiving ILE C program. The variable item_name is null ended in the CL program.
To create a CL command prompt T1520CM2 using the source in Figure 3, enter:
/* This program demonstrates the interlanguage call capability */
/* of an ILE C program. This program is called by a CL */
/* program that passes an item name, price, quantity and user ID. */
/* A COBOL procedure is called to calculate and format total cost.*/
/* An RPG procedure is called to write an audit trail. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <decimal.h>
/* The #pragma map directive maps a function name to the bound */
/* procedure name so that the purpose of the procedure is clear. */
#pragma map(calc_and_format,"T1520CB2")
#pragma map(write_audit_trail,"T1520RP2")
/* Tell the compiler that there are bound procedure calls and */
/* arguments are to be passed by value-reference. */
#pragma argument(calc_and_format, OS, nowiden)
#pragma argument(write_audit_trail, OS)
void calc_and_format(decimal (10,2),
short int,
char[],
char *);
void write_audit_trail(char[],
char[],
decimal(10,2),
short int,
char[]);
extern decimal (2,2) TAXRATE; /* TAXRATE is in *SRVPGM T1520SP3 */
int main(int argc, char *argv[])
{
/* Incoming arguments from a CL program have been verified by */
/* the *CMD and null ended within the CL program. */
/* Incoming arguments are passed by reference from a CL program. */
char *user_id;
char *item_name;
short int quantity;
decimal (10, 2) price;
char formatted_cost[22];
/* Remove null terminator for RPG for iSeries program. Item name is null */
/* ended for C. */
char rpg_item_name[20];
char null_formatted_cost[22];
char success_flag = 'N';
int i;
/* Incoming arguments are all pointers. */
item_name = argv[1];
price = *((decimal (10, 2) *) argv[2]);
quantity = *((short *) argv[3]);
user_id = argv[4];
/* Call the COBOL program to do the calculation, and return a */
/* Y/N flag, and a formatted result. */
calc_and_format(price,
quantity,
formatted_cost,
&success_flag);
memcpy(null_formatted_cost,formatted_cost,sizeof(formatted_cost));
/* Null end the result. */
formatted_cost[21] = '\0';
if (success_flag == 'Y')
{
for (i=0; i<20; i++)
{
/* Remove the null end for the RPG for iSeries program. */
if (*(item_name+i) == '\0')
{
rpg_item_name[i] = ' ';
}
else
{
rpg_item_name[i] = *(item_name+i);
}
}
/* Call an RPG program to write audit records. */
write_audit_trail(user_id,
rpg_item_name,
price,
quantity,
formatted_cost);
printf("\n%d %s plus tax = %-s\n", quantity,
item_name,
}
else
{
printf("Calculation failed\n");
}
}
Note:
The main() function in this module receives the incoming arguments from the ILE CL program T1520CL3 that are verified by the CL command T1520CM2 and null ended within the CL program T1520CL3. All the incoming arguments are pointers.
The main() function in this program calls calc_and_format() which is mapped to a ILE COBOL procedure name. It passes by OS-linkage convention the price, quantity, formatted cost, and a success flag. The ILE OPM COBOL procedure is not expecting widened parameters, the default for ILE C. This is why nowiden is used in the #pragma argument directive. The formatted cost and the success flag values are updated in the procedure T1520CB2.
If calc_and_format() return successfully the main() function in this program (T1520ICB) calls write_audit_trail() which is mapped to an ILE RPG procedure name. It passes by OS-linkage convention (also called by value-reference) the user ID, item name, price, quantity, and formatted cost. The ILE C compiler by default converts a short integer to an integer unless the nowiden parameter is specified on the #pragma argument directive. For example, the short integer in the ILE C program is converted to an integer, and then passed to the ILE RPG procedure. The RPG procedure is expecting a 4 byte integer for the quantity variable.
To create module T1520ICC using the source shown in Figure 4, enter:
TAXRATE is exported from this module to ILE C, COBOL, and RPG procedures.
Note:Weak definitions (EXTERNALs from COBOL) cannot be exported out of a service program to a strong definition language like C. C can export to COBOL, hence the choice of language for TAXRATE.
To create an ILE COBOL procedure using the source shown in Figure 5, enter:
Figure 6. T1520RP2 — ILE RPG Source to Write the Audit Trail
FT1520DD2 O A E DISK
D TAXRATE S 3P 2 IMPORT
D QTYIN DS
D QTYBIN 1 4B 0
C *ENTRY PLIST
C PARM USER 10
C PARM ITEM 20
C PARM PRICE 10 2
C PARM QTYIN
C PARM TOTAL 21
C EXSR ADDREC
C SETON LR
C ADDREC BEGSR
C MOVEL UDATE DATE
C MOVE QTYBIN QTY
C MOVE TAXRATE TXRATE
C WRITE T1520DD2R
C ENDSR
Note:
The write_audit_trail() function is the procedure T1520RP2. It writes the audit trail for the program.
The ILE RPG Programmer's Guide contains information on how to compile an ILE RPG source program.
To create the service program T1520SP3 from the module T1520ICC, enter: