REXX is the favourite for many TSO programmers worldwide, because it is easy and fast to write a REXX program. REXX integrates beautiful with ISPF and TSO and many software products has REXX interfaces. These interfaces make it possible to access DB2, MQ and many other software products from REXX. In this tip I will tell you about different methods of calling a LOAD module from REXX. These LOAD modules typically are the result of compiling programs written in PL/1, COBOL, VAG, C, assembler or other languages requiring a compilation.
You can use three different methods to call a LOAD module in REXX. You can execute an ADDRESS LINK "LMODNAME". Replace LMODNAME with the name of the LOAD module you want to execute and REXX will immediately execute this LOAD module. You can transfer parameters to the LOAD module with ADDRESS LINK, but they will not be understood by 99% of all LOAD modules made for MVS. Therefore I recommend you not to use ADDRESS LINK if you want to transfer parameters to your LOAD module.
The second method is invoked using ADDRESS LINKMVS "LMODNAME PARM". Please replace LMODNAME with your LOAD module name and replace PARM with the name of the REXX variable containing the parameter you want to transfer to the LOAD module. An example:
This piece of REXX code works in exactly the same way as EXEC PGM=MYPGM,PARM='HELLO WORLD' works in JCL.
The third method is activated using ADDRESS LINKPGM "LMODNAME PARM1 PARM2 PARM3 ..." and is the recommended method of calling all kinds of LOAD modules that are in compliance with the MVS standard linkage convention. All COBOL LOAD modules are in compliance as well as most LOAD modules for MVS software. Unfortunately PL/1 does not comply unless you do something special. If you want to call MQ directly from REXX it can be done using ADDRESS LINKPGM. Let me illustrate the use of ADDRESS LINKPGM with a COBOL example:
You can call this COBOL program from REXX in the following way:
The variable PARM1 is easy to transfer because a character string in REXX is build in the same way as in COBOL, but it is important to use the same number of bytes in REXX as the varable occupies in COBOL. The variable PARM2 is a so-called halfword (SMALLINT in DB2, FIXED BIN(15) in PL/1). A halfword occupies two bytes, therefore you must build a character string of two bytes in REXX containing the value you want to transfer. This is done by using the REXX built in function D2C. If PARM2 were a fullword in the example, you had to use D2C(1000,4) instead. By using ADDRESS LINKPGM it is very easy to create drivers in REXX that calls programs written in other programming languages.
The three methods of calling a LOAD module from REXX each has a sister called ATTACH instead of LINK which becomes ATTACH, ATTACHMVS and ATTACHPGM. ATTACH* creates a new TCB for the LOAD module to be executed in instead of executing it in the callers TCB. I have not tried ATTACH* so I cannot explain exactly how it works. In MVS terms ATTACH is the method used to execute more than one LOAD module in parallel in the same address space though I am pretty sure that REXX will not execute anything in parallel. When you use ATTACH* or LINK* the REXX variable RC will contain the return-code set by the called LOAD module.