Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C -> COBOL interlanguage communication on mainframe

Tags:

A vendor package written in C on the mainframe offers the option to override a portion of it's functionality via a user exit. The provided C function prototype is:

extern int SomeExit (void * Parameters,
                     void * Record1,
                     void * Record2,
                     char ComparisonType,
                     char * RankString,
                     void * NotUsed1,
                     int * NotUsed2)

As we are primarily a COBOL shop I defined an Enterprise COBOL 4.2 program (as a DLL) to implement the exit trying to follow the conventions given in the IBM ILC guide (https://www.ibm.com/support/knowledgecenter/en/SSLTBW_1.13.0/com.ibm.zos.r13.ceea400/clcccb5.htm#clcccb5) and the examples in this old SHARE presentation: http://www-01.ibm.com/support/docview.wss?uid=swg27003846&aid=1 but the resulting program is abending as it calls the exit and prior to my DISPLAY message. My assumption is that I have not declared the receiving data structures correctly. Below is a snippet of my current test code (ignore my naming conventions - this is a prototype to prove out the interface and will be rewritten to our in-house standards once I have the basic call working).

IDENTIFICATION DIVISION.   
PROGRAM-ID.    "SomeExit". 
...
LINKAGE SECTION.                                               
01  WS-PARAMETERS-POINTER       USAGE IS POINTER SYNCHRONIZED. 
01  SORT-PASS-RECORD1-POINTER   USAGE IS POINTER SYNCHRONIZED. 
01  SORT-PASS-RECORD2-POINTER   USAGE IS POINTER SYNCHRONIZED. 
01  WS-COMPARISION-TYPE         PIC X.
01  WS-RANK-STRING-POINTER      USAGE IS POINTER SYNCHRONIZED. 
01  WS-NOT-USED1-POINTER        USAGE IS POINTER SYNCHRONIZED. 
01  WS-NOT-USED2-POINTER        USAGE IS POINTER SYNCHRONIZED. 
01  WS-RETURN                   PIC S9(9) USAGE IS BINARY.
...
PROCEDURE DIVISION USING BY VALUE WS-PARAMETERS-POINTER     
                     SORT-PASS-RECORD1-POINTER          
                     SORT-PASS-RECORD2-POINTER          
                     WS-COMPARISION-TYPE                
                     WS-RANK-STRING-POINTER             
                     WS-NOT-USED1-POINTER               
                     WS-NOT-USED2-POINTER               
               RETURNING WS-RETURN.                     

DISPLAY 'IN EXIT'.
... 
MOVE 0 TO WS-RETURN.
GOBACK.

The abend is:

CEE3250C The system or user abend U 016 R=00000000 was issued.                                                     
     From entry point main at compile unit offset +00000192 at entry offset +00000192 at address 28500ECA.     

The vendor code calls the DLL dynamically. When I delete the DLL I get a message that the exit cannot be found and so it seems like the C code is attempting to call it.

I have tried variations on the PROCEDURE DIVISION USING including dropping the BY VALUE, using BY REFERENCE (though I understand that is the default) and replacing the POINTERs with the actual structure definitions. Have I misunderstood the manual on how to structure the parameters passed to the COBOL routine?

Edit: I do have a support ticket open with the vendor but they have not responded with anything useful yet.

Thanks, David

like image 435
David Doyle Avatar asked Nov 02 '16 22:11

David Doyle


1 Answers

Thanks to the comments I was able to determine a solution based on better understanding of the calling structure per Bills suggestion. Given this C prototype:

extern int SomeExit (void * Parameters,
                     void * Record1,
                     void * Record2,
                     char ComparisonType,
                     char * RankString,
                     void * NotUsed1,
                     int * NotUsed2)

The solution:

IDENTIFICATION DIVISION.     
PROGRAM-ID.    "SomeExit".   
...
LINKAGE SECTION.      
01  WS-PARAMETERS        PIC X(10).    
01  SORT-PASS-RECORD1    PIC X(50).    
01  SORT-PASS-RECORD2    PIC X(50).    
01  WS-COMPARISON-TYPE   PIC X.
01  WS-RANK-STRING       PIC X(6).                  
01  WS-NOT-USED1         PIC X.                     
01  WS-NOT-USED2         PIC X.                     
01  WS-RETURN            PIC S9(9) USAGE IS BINARY.
... 
PROCEDURE DIVISION USING                     
        BY REFERENCE WS-PARAMETERS       
        BY REFERENCE SORT-PASS-RECORD1   
        BY REFERENCE SORT-PASS-RECORD2   
        BY VALUE     WS-COMPARISON-TYPE  
        BY REFERENCE WS-RANK-STRING      
        BY REFERENCE WS-NOT-USED1        
        BY REFERENCE WS-NOT-USED2        
           RETURNING WS-RETURN.          
    DISPLAY 'IN EXIT'.
    ... 
    MOVE 0 TO WS-RETURN.
    GOBACK.

With the above the user exit was successfully called and returned a value to the vendor logic. I used the following parameters for compilation RENT, TRUNC(BIN), DLL,EXPORTALL and for linking DYNAM(DLL),RENT. Not needed for my application but if the calling program is expecting a mixed case routine name in the called program as used in the above example solution then PGMNAME(LONGMIXED) would have been needed also.

Thanks to all the commenters for pointing me in the right direction.

like image 102
David Doyle Avatar answered Sep 22 '22 16:09

David Doyle