On Tue, 21 Mar 2006 13:47:20 -0500, john stephens <[EMAIL PROTECTED]> wrote: >I need to be able to have this routine dynamically linked at run time if/when >the user requries. Therefore, I need to be able to compile and link this >routine without a 'main'. I can live with the di/tri-graphs if need be. > >As far as linking goes, the JCL I was given has a compile proc step, a >pre-link proc step and a link proc step. Unfortunatly, neither of the last >two will run cleanly. >
Here is the JCL to compile and statically link a C subroutine CSUB to a COBOL mainline COBMAIN. You'll have to change dataset names etc. NB caps off //COMPILE EXEC PGM=CCNDRVR, // REGION=100M,COND=(4,LT), // PARM='/OPTF(DD:O)' //O DD * AGG SHOW NOSEQ MAR(1,172) INL(AUTO,REPORT,999,999999) EXPMAC RENT LO SO NOSEARCH LIS SS ARCH(5) OPT(1) //STEPLIB DD DSNAME=SYS1.SCCNCMP,DISP=SHR //SYSMSGS DD DUMMY,DSNAME=SYS1.SCEEMSGP(EDCMSGE),DISP=SHR //SYSLIN DD DSNAME=&&OBJ,UNIT=VIO, // DISP=(NEW,PASS),SPACE=(TRK,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSCPRT DD SYSOUT=* //SYSUT1 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=80,RECFM=FB //SYSUT4 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=80,RECFM=FB //SYSUT5 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=3200,RECFM=FB //SYSUT6 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=3200,RECFM=FB //SYSUT7 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=3200,RECFM=FB //SYSUT8 DD UNIT=VIO,SPACE=(32000,(90,900)),LRECL=3200,RECFM=FB //SYSUT9 DD UNIT=VIO,SPACE=(32000,(90,900)), // DCB=(RECFM=VB,LRECL=137,BLKSIZE=882) //SYSUT10 DD SYSOUT=* //SYSUT14 DD UNIT=VIO,SPACE=(32000,(90,930)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //* //SYSIN DD * ??=pragma linkage(CSUB,COBOL) ??=include <stdlib.h> ??=include <stdio.h> ??=include <string.h> extern void CSUB( void* void_key_ptr ) ??< char * key_ptr; key_ptr = void_key_ptr; * (key_ptr) = 'F'; return; ??> //USERLIB DD DISP=SHR,DSN=JLP.TEST.MVSCHDR // DD DISP=SHR,DSN=JLP.TEST.MVSCSRC // DD DISP=SHR,DSN=JLP.TEST.CSRC //SYSLIB DD DSN=SYS1.SCEEH.H,DISP=SHR // DD DSN=SYS1.SCEESAMP,DISP=SHR // DD DSN=SYS1.SCEEH.SYS.H,DISP=SHR //* //* PRE-LINKEDIT STEP: //* //PLKED EXEC PGM=EDCPRLK,COND=(4,LT),REGION=7M, // PARM='' //SYSMSGS DD DSNAME=SYS1.SCEEMSGP(EDCPMSGE),DISP=SHR //SYSMOD DD DSNAME=JLP.TEST.OBJ(CSUB),DISP=SHR //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSIN DD DSN=&&OBJ,DISP=(SHR,DELETE) // DD * //SYSLIB DD DISP=SHR,DSN=JLP.TEST.OBJ //* //* STANDARD COBOL COMPILE //* //C EXEC PGM=IGYCRCTL,COND=(4,LT),REGION=7M, // PARM=('NOOFFSET,NOSSRANGE,RENT,LIST,NOCICS,OPT(FULL),', // 'NODYNAM,LIB,APOST,') //STEPLIB DD DISP=SHR,DSN=SYSPP.COBOS330.SIGYCOMP //SYSUT1 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT2 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT3 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT4 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT5 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT6 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSUT7 DD UNIT=VIO,SPACE=(6233,(150,300),,,ROUND) //SYSLIN DD DSN=&&OBJ,DISP=(NEW,PASS),BLKSIZE=3120, // UNIT=VIO,SPACE=(80,(1500,7750)) //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=JLP.TEST.MVSCOB // DD DISP=SHR,DSN=JLP.TEST.COPYLIB // DD DISP=SHR,DSN=JLP.TEST.COBOL // DD DSN=SYS1.SCEESAMP,DISP=SHR 000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. 'COBMAIN'. 000300 ENVIRONMENT DIVISION. 000400 DATA DIVISION. 000500 WORKING-STORAGE SECTION. 000600 01 W-X PIC X. 001900 PROCEDURE DIVISION. 002100 002200 MOVE 'I' TO W-X 002300 DISPLAY 'COBMAIN ENTERED X=' W-X 002301 002310 DISPLAY 'CALLING CSUB' 002400 002500 CALL 'CSUB' USING W-X 002510 DISPLAY 'CALLED CSUB X=' W-X 003400 003500 MOVE 0 TO RETURN-CODE 003600 STOP RUN . //* //* PRE-LINKEDIT STEP: //* //PLKED EXEC PGM=EDCPRLK,COND=(4,LT),REGION=7M, // PARM='' //SYSMSGS DD DSNAME=SYS1.SCEEMSGP(EDCPMSGE),DISP=SHR //SYSMOD DD DSNAME=&&OBJ,UNIT=VIO,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //SYSIN DD DSN=&&OBJ,DISP=(SHR,DELETE) // DD * //SYSLIB DD DISP=SHR,DSN=JLP.TEST.OBJ //* //LINK EXEC PGM=HEWL,COND=(4,LT), // PARM=('XREF,LIST,MAP', // 'AMODE=31,RMODE=ANY,RENT,REUS') //SYSUT1 DD UNIT=VIO,SPACE=(1024,(100,30)) //SYSPRINT DD SYSOUT=* //SYSLMOD DD DSN=JLP.TEST.LOADLIB(COBMAIN),DISP=SHR //SYSLIB DD UNIT=VIO,SPACE=(1,(1,1,1)),BLKSIZE=32760,RECFM=U // DD DSN=SYS1.SCEELKED,DISP=SHR //CICSLINK DD DSN=CICSSYS.CTSLEVEL.CICS.SDFHEXCI,DISP=SHR // DD DSN=CICSSYS.CTSLEVEL.CICS.SDFHLOAD,DISP=SHR //SYSLIN DD DSN=&&OBJ,DISP=(OLD,DELETE) // DD * //RUNIT EXEC PGM=COBMAIN //STEPLIB DD DSN=JLP.TEST.LOADLIB(COBMAIN),DISP=SHR //SYSOUT DD SYSOUT=* //SYSUDUMP DD SYSOUT=* This is static not dynamic linkage but bear with me We faced similar problems to you with the additional constraint that we had to call our dynamically loadable subroutines from Assembler, Cobol, non-LE-compliant assembler, and C mains, all of them pre-existing and some calling old routines written in assembler or COBOL which we wanted to replace by C routines of the same name. Some of these calls used dynamic COBOL load, some used the LOAD macro. We could not use DLL because you can't mix DLLs and COBOL dynamic load in one run unit. Our solution was to wrap our C routines in a small COBOL wrapper, then they look to everything like COBOL. You just call your C code from a cobol program (as above) but you make the COBOL program a subroutine and call the COBOL subroutine from your mainlines. Inelegant but works robustly. If you can create a new clean run time environment and you have no assembler you can go for DLL on MVS (I can show you how to do this as well). c ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to [EMAIL PROTECTED] with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html