Chapter Contents

Previous

Next
Using the indep Option for Interlanguage Communication

Sample Interlanguage Calls

The following paragraphs discuss an example of calling C indep code from PL/I. The C code in turn calls PL/I. Sample L$URTOP Routine manipulates bits in PL/I save areas to prevent inspection of C save areas for ON-units. Although this manipulation keeps PL/I from getting confused in most cases, it cannot be guaranteed to work in all cases or with all versions of the PL/I library.

First, the L$UCENV macro is modified to locate the user word of the PL/I TCA (TUSR). The address of TUSR is returned in register 12, which, after completion of L$UCENV, is expected to contain the address of the word in which L$UPREP should store the CRAB address. This modified version of L$UCENV also performs a secondary function, namely, storing the address of the most recent PL/I save area in a CRAB user word so it can be used later when reentering the PL/I execution framework.

L$UCENV Macro for PL/I to C shows this version of L$UCENV.


L$UCENV Macro for PL/I to C
MACRO &L L$UCENV &L LA R12,X'11C'(,R12) Access TCA user word. CLC 0(4,R12),=F'0' CRAB address known yet? BE CENV&SYSNDX If NO, no place to save SAVE area ST R12,8(,R13) Save R12 for a moment. L R12,0(,R12) Find the CRAB. USING CRAB,R12 ST R13,CRABUSR1 Save SAVE area addr in CRAB. DROP R12 L R12,8(,R13) Restore CRAB pointer address. CENV&SYSNDX DS 0H MEND

Second, the L$UPENV macro must be provided. The example L$UPENV works fine in this context since L$UPENV REG=12 retrieves the PL/I TCA address.

Finally, an assembler routine must be written to allow calls from C to PL/I. A sample routine to perform this service, PLISUB, is shown in Sample PLISUB Routine. The first argument to the procedure is the address of the PL/I routine; the remaining arguments are those to be passed to PL/I. The PLISUB routine must

  1. locate the PL/I routine's actual entry point

  2. switch to the PL/I execution framework by using L$UPENV

  3. build a save area for itself that looks enough like a PL/I DSA to avoid confusing the PL/I library.

When the PL/I routine returns, PLISUB must put everything back before returning. A sample call to PLISUB to perform the equivalent of the PL/I call CALL TRANS(I, 2); follows:

extern trans();
plisub(&trans, @i, @2);


Sample PLISUB Routine
PLISUB@ CSECT CREGS USING CRAB,R12 PLISUB CENTRY DSA=DSALEN L R2,0(,R1) Address PL/I "function pointer." L R2,0(,R2) Address PL/I entry point. LA R3,4(,R1) Address PL/I program's parms. LR R4,R12 Save CRAB address. DROP R12 USING CRAB,R4 L$UPENV REG=12 Find the PL/I TCA. LR R6,R13 Save our DSA address. USING DSA,R6 Establish DSA addressability. MVC 0(2,R6),=X'8200' Mark it as a dummy PL/I DSA. LA R13,PLIDSA Find a save area for PL/I to use. XC 0(96,R13),0(R13) ST R6,4(,R13) Link to our SAVE area. MVC 0(4,R13),=X'80000000' INIT SAVE area for PL/I MVC 86(2,R13),=X'91C0' as described in PL/I doc ICM R7,15,CRABUSR1 Find last PL/I SAVE area BNZ OK L R7,CRABPENV or save area on entry to C. OK DS 0H MVC 72(8,R13),72(R7) Copy PL/I storage management O LR R15,R2 Set up regs for call. LR R1,R3 Put address of parms where PL/I expects. BALR R14,R15 Call PL/I. LR R13,R6 Restore our own SAVE area LR R12,R4 and R12. ST R7,CRABUSR1 Restore CRAB PL/I SAVE area ptr. CEXIT , Return to C. SPACE LTORG COPY CRAB SPACE COPY DSA SPACE PLIDSA DS CL96 Space for PL/I SAVE area. SPACE DSALEN EQU *-DSA END


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.