MainframeSupports
tip uge 21/2004:

REXX har vundet mange tilhængere verden over, fordi det er nemt og hurtigt at kode et REXX-program. REXX kan også ret nemt udstede TSO og ISPF kommandoer og derudover har diverse software leverandører lavet interfaces til REXX, der gør det muligt at kalde eksempelvis DB2 og MQ og meget andet. Men hvordan kalder man egentlig et program skrevet i et andet programmeringssprog end REXX. Jeg vil i dette tip gennemgå forskellige metoder til at kalde LOAD-moduler, som typisk er resultatet af at skrive programmer i PL/1, COBOL, VAG, C, assembler eller andre compilerende sprog.

Der findes tre forskellige kalde-metoder i REXX. Den første er at udstede en ADDRESS LINK "LMODNAME". Erstat LMODNAME med navnet på det LOAD-modul, du vil kalde, så eksekverer REXX straks det pågældende LOAD-modul. Man kan angive parametre til LOAD-modulet, men de vil ikke kunne forstås af 99% af alle de LOAD-moduler, der er lavet til MVS, så derfor skal man i mine øjne holde sig langt væk fra ADDRESS LINK, hvis man gerne vil overføre parametre til det kaldte LOAD-modul.

Den anden metode kaldes med en ADDRESS LINKMVS "LMODNAME PARM". Igen erstattes LMODNAME med navnet på det LOAD-modul, du vil kalde. PARM erstattes med navnet på den REXX-variabel, der indeholder den parameter, du vil overføre til programmet. Et eksempel:

/* REXX */
MYPARM = 'HELLO WORLD'
ADDRESS LINKMVS "MYPGM MYPARM"

Ovenstående REXX virker på præcis samme måde som EXEC PGM=MYPGM,PARM='HELLO WORLD' virker i JCL.

Den tredie metode aktiveres med ADDRESS LINKPGM "LMODNAME PARM1 PARM2 PARM3 ...". Denne metode er vejen frem til kald af alle mulige LOAD-moduler, som overholder MVS standard linkage konventionen. Det gør eksempelvis alle COBOL load-moduler. Alle LOAD-moduler tilhørende software til MVS-platformen overholder ogåså denne konvention. PL/1 gør desværre ikke, med mindre man gør noget særligt. Hvis man vil kalde MQ direkte fra REXX, så kan det faktisk lade sig gøre med ADDRESS LINKPGM. Lad mig illustrere med et COBOL eksempel:

IDENTIFICATION DIVISION.
PROGRAM-ID. MYCOBPGM.
...
LINKAGE SECTION.
77  PARM1 PIC X(8).
77  PARM2 PIC S9(4) COMP.
PROCEDURE DIVISION USING PARM1, PARM2.
...

Dette COBOL-program kaldes fra REXX på følgende måde:

/* REXX */
PARM1 = 'FIRSTVAL'
PARM2 = D2C(1000,2)
ADDRESS LINKPGM "MYCOBPGM PARM1 PARM2"

Variablen PARM1 er let at overføre, da en tegnstreng i REXX er som en tegnstreng i COBOL. Det er dog vigtigt, at overføre netop det antal tegn, som variablen fylder i COBOL. Variablen PARM2 er et såkaldt halvord (SMALLINT i DB2, FIXED BIN(15) i PL/1). Et halvord fylder 2 bytes, så derfor er det nødvendigt at lave en tegnstreng i REXX på to bytes, som indeholder den værdi, man gerne vil overføre. Det gøres lettest med D2C funktionen. Hvis PARM2 havde været et helord, så skulle der i eksemplet i stedet have stået D2C(1000,4). Det geniale ved ADDRESS LINKPGM er, at det med denne kommando er uhyre simpelt at skrive drivere i REXX til programmer skrevet i andre sprog.

Til sidst skal jeg huske at nævne, at de tre metoder hver har en søster, som hedder ATTACH i stedet for LINK, altså ATTACH, ATTACHMVS og ATTACHPGM. ATTACH gør, at det kaldte LOAD-modul bliver afviklet under sin en TCB i stedet for kalderens TCB. Præcist hvordan det virker i REXX har jeg ikke prøvet. ATTACH er i MVS termer måden at afvikle flere LOAD-moduler parallelt i samme address space, men jeg tror godt nok ikke, at REXX laver en parallel afvikling af det kaldte program. Uanset om du har brugt LINK* eller ATTACH*, så vil REXX-variablen RC indeholde returkoden fra det kaldte program.

Forrige danske tip        Last tip in english        Tip oversigten