C/C++

C/C++

C/C++

Your one-stop destination to learn and collaborate about the latest innovations in IBM C/C++ for z/OS compilers to develop high-performing C/C++ applications and system programs on z/OS while maximizing hardware use and improving application performance.

 View Only
Expand all | Collapse all

C-Module in PL1-Main-Programm

  • 1.  C-Module in PL1-Main-Programm

    Posted Wed February 07, 2018 10:02 AM

    Hi,

     

    maybe my task is very simple but I dont know how to do it.

    I want to call a c-subroutine from a pl1-mainprogram.

     

    For now it would be enough that the subroutine just say hello.

    Here are some extracts of my sourcecode:

    C:

    #pragma linkage(CTEST,PLI)               
    void CTEST ();                           
    void CTEST(void)                         
    {                                       
       printf("Viel Spass mit C");           
    }

     

    PL1:

             DCL CTEST  EXTERNAL ENTRY OPTIONS (LINKAGE(SYSTEM));         
             FETCH CTEST;                                                 
    -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 20 Line(s) not Displayed
                                                                          
     CPROG: PROC;                                                         
         CALL CTEST;                                                      
     END CPROG;                                                           
                                          

     

     

     

    The result is "ONCODE =     9251" when reaching "FETCH CTEST;    "

     

    What can I do?

    Thank you.
     

     

    MetatronsCube


  • 2.  Re: C-Module in PL1-Main-Programm

    Posted Fri April 13, 2018 05:10 PM

    I would delete the #pragma linkage and the OPTIONS(LINKAGE(SYSTEM)). These are not needed if you are using Enterprise PL/I, and I think they may be creating a mismatch.

    It is also important to specify matching compiler options; in particular, if you compile the C code with the C compiler's RENT option, you must also compile the PL/I code with the compiler's RENT option and vice versa.

     

    There's a lot more on this topic in the Programming Guide, but here is some working JCL for a job that will fetch and invoke a C routine from PL/I

     

    //*
    //COMPNAME SET  CNAME=CCNDRVR
    //CRELEASE SET  CRLSE=SCCNCMP
    //LELEVEL  SET  LEHLQ=CEEV2R1Z
    //*
    //*
    //PLI EXEC PGM=IBMZPLI,PARM='s'
    //STEPLIB   DD DISP=SHR,DSN=ENPLI450.SIBMZCMP
    //CEEDUMP   DD SYSOUT=X
    //SYSPRINT  DD SYSOUT=X
    //SYSLIN    DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSSQ,
    //             SPACE=(CYL,(3,1))
    //SYSUT1    DD DSN=&&SYSUT1,UNIT=SYSDA,
    //             SPACE=(1024,(200,50),,CONTIG,ROUND),DCB=BLKSIZE=1024
    //SYSIN     DD *
    *process;
     test: proc options(main);
       dcl rc fixed bin(31);
       dcl CSUB ext entry( fixed bin(31) byvalue,
                           fixed bin(31) byvalue )
                    returns( fixed bin(31) byvalue );
       fetch CSUB;
       rc = CSUB(1,2);
     end;
    //*********************************************************************
    //BINDMAIN  EXEC PGM=IEWL,PARM='XREF,LIST,LET,RENT,DYNAM(DLL)',
    //    COND=(7,LT),REGION=5000K
    //SYSLIB   DD  DISP=SHR,DSN=&LEHLQ..SCEELKED
    //SYSLMOD  DD DSN=&&GOSET(GO),DISP=(MOD,PASS),UNIT=SYSDA,
    //   SPACE=(CYL,(1,1,1)),DSNTYPE=LIBRARY
    //SYSUT1   DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(CYL,(3,1)),
    //            DCB=BLKSIZE=1024
    //SYSPRINT DD DUMMY
    //SYSDEFSD DD DUMMY
    //SYSLIN    DD DSN=&&LOADSET,DISP=SHR
    //         DD DDNAME=SYSIN
    //LKED.SYSIN     DD *
      ORDER CEESTART
    //**
    //**
    //*
    //*******  ****
    //COMPSUB  EXEC  PGM=&CNAME.,PARM='OPTFILE(DD:COPTSUB)'
    //*******  ****
    //STEPLIB  DD  DISP=SHR,DSN=CBC.&CRLSE
    //         DD  DISP=SHR,DSN=&LEHLQ..SCEERUN
    //COPTSUB  DD  *
    FLAG(I),LIST,SOURCE,XREF
    /*
    //SYSLIB   DD  DISP=SHR,DSN=&LEHLQ..SCEEH.H
    //         DD  DISP=SHR,DSN=&LEHLQ..SCEEH.SYS.H
    //SYSLIN   DD  SPACE=(CYL,(1,1)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200),
    //             DISP=(MOD,PASS),UNIT=SYSDA,DSN=&&OBJCSUB
    //SYSPRINT DD  SYSOUT=*
    //SYSOUT   DD  SYSOUT=*
    //SYSCPRT  DD  SYSOUT=*
    //SYSUT1   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
    //SYSUT4   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
    //SYSUT5   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT6   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT7   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT8   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT9   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)
    //SYSUT10  DD  SYSOUT=*
    //SYSUT14  DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT15  DD  SYSOUT=*
    //SYSIN    DD  *

     int CSUB2();

     int CSUB  (int a, int b)
     {
        int rc;
        int (*fun)();
        printf("  Into the C sub...\n");
        printf("  assigning fun\n");
        fun = CSUB2;
        printf("  calling CSUB2\n");
        rc = (*fun)();
        printf("  Returning parameters times 3 from NORENT C sub\n");
        return( (a*b)*rc );
     }
    /*
    //*
    //*******  ****
    //COMPSUB2  EXEC  PGM=&CNAME.,PARM='OPTFILE(DD:COPTSUB)'
    //*******  ****
    //STEPLIB  DD  DISP=SHR,DSN=CBC.&CRLSE
    //         DD  DISP=SHR,DSN=&LEHLQ..SCEERUN
    //COPTSUB  DD  *
    FLAG(I),LIST,PHASEID,SOURCE,XREF
    /*
    //SYSLIB   DD  DISP=SHR,DSN=&LEHLQ..SCEEH.H
    //         DD  DISP=SHR,DSN=&LEHLQ..SCEEH.SYS.H
    //SYSLIN   DD  SPACE=(CYL,(1,1)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200),
    //             DISP=(MOD,PASS),UNIT=SYSDA,DSN=&&OBJCSUB2
    //SYSPRINT DD  SYSOUT=*
    //SYSOUT   DD  SYSOUT=*
    //SYSCPRT  DD  SYSOUT=*
    //SYSUT1   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
    //SYSUT4   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
    //SYSUT5   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT6   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT7   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT8   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT9   DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)
    //SYSUT10  DD  SYSOUT=*
    //SYSUT14  DD  UNIT=VIO,SPACE=(3200,(30,30)),
    //             DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
    //SYSUT15  DD  SYSOUT=*
    //SYSIN    DD  *

     int test = 0;

     int CSUB2 ()
     {
        printf("  Into the RENT C sub...\n");
        test = test + 3;
        return( test );
     }
    /*
    /*
    /*
    //*******  ****
    //BINDSUB  EXEC  PGM=IEWL,COND=(4,LT,COMPSUB),
    //    PARM='LET,LINECT(0),LIST,MAP,XREF,DYNAM(DLL),RENT'
    //*******  ****
    //SYSLIB   DD  DISP=SHR,DSN=&LEHLQ..SCEELKED
    //SYSPRINT DD  SYSOUT=*
    //OBJECT   DD  DISP=(OLD,DELETE),DSN=&&OBJCSUB
    //         DD  DISP=(OLD,DELETE),DSN=&&OBJCSUB2
    //SYSLMOD  DD DSN=&&FETSET(CSUB),DISP=(MOD,PASS),UNIT=SYSDA,
    //   SPACE=(CYL,(1,1,1)),DSNTYPE=LIBRARY
    //SYSUT1   DD  DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1024,(200,20)),
    //             DCB=BLKSIZE=1024
    //SYSLIN   DD  *
      INCLUDE  OBJECT
      ENTRY    CSUB
      NAME     CSUB(R)
    /*
    //*
    //****     ****
    //GO      EXEC PGM=*.BINDMAIN.SYSLMOD,COND=(7,LT)
    //****     ****
    //STEPLIB  DD  DISP=SHR,DSN=&&FETSET
    //         DD  DISP=SHR,DSN=&LEHLQ..SCEERUN
    //CEEDUMP  DD  SYSOUT=X
    //SYSPRINT DD  SYSOUT=*
    //STDOUT   DD  SYSOUT=*

     

     

     

    pelderon