Menu

COBOL and C linkages with FFI -- help needed..

Anonymous
2022-07-14
2022-07-16
  • Anonymous

    Anonymous - 2022-07-14

    Hi again,
    Hoping you can help me get C to COBOL to C linkages working. I am having some challenges, have tried lots of things and still have no idea where the issue is.

    https://github.com/adelosa/gnucob-ffi

    I have simplified and recreated the issue in the above GitHub repo.
    It also has some explanations on what I am trying to do.

    I can't work out why the parameter parsing works on the first C->COBOL call but on the subsequent call (C->COBOL-C->COBOL) it says that the second linkage area has not been passed.. but I have.. And I can't work it out because the first linkage area is fine and I use the same process for both.

    I suspect its just my bad programming.. but I just can't see it.
    Any pointers would be appreciated. Feel free to ask any questions..

    Anthony

     
    • Simon Sobisch

      Simon Sobisch - 2022-07-15

      Found what should be in the Manual included in the testsuite. Using your original program and GnuCOBOL 3 your "C2" program must explicit tell the COBOL runtime that it did not get the same number of parameters that were used in the last COBOL CALL.

      To do so:

      cob_get_global_ptr()->cob_call_params = 2;
      

      We still should have a look at your second example.

       
  • A Delosa

    A Delosa - 2022-07-14

    Sorry.. forgot to log in before positing.. It's me!

     
  • Simon Sobisch

    Simon Sobisch - 2022-07-14

    Please have a look at "C interface" in the GnuCOBOL manual, source and generated PDF.

     
  • Simon Sobisch

    Simon Sobisch - 2022-07-14

    Hm, that was less helpful than I've thought.

    For this scenario the easiest setup would be to use cob_call, but this does not seem to be possible directly as you want to use it with a function pointer.

    In this case - using GnuCOBOL 3 - the easiest option is to use a C wrapper passing that's function pointer - and from there use cob_call.

    Background: first COBOL module "sees" that there is no COBOL in stack and internally sets the number of linkage arguments depending on "not null", then it does a CALL and in there sets "I pass only 1 argument", then C comes, calls the second COBOL program which sees COBOL in stack and then takes "there was one item used for CALL".

     
  • A Delosa

    A Delosa - 2022-07-15

    Hi Simon -- thanks for the response. From what I can tell the cob_call function has the same signature as my call_cobmodule function.

    I replaced the call but I get the same outcome.. Have I understood what you are saying correctly or am I not using cob_call correctly..

    The following is my changes to ccall.c

    #include <ffi.h>
    #include <libcob.h>
    #include <stdio.h>
    
    static void (*cobmodule)(void);
    int call_cobmodule(char * module, int num_linkage_areas, void ** linkage_areas);
    
    struct linkage1 {
        void * linkage_area;         // pointer linkage_area
        char data[20];              // tran number (FW)
    };
    
    void ccall(struct linkage1 * linkage1) {
    
        printf("%s\n", linkage1->data);
        void ** linkage_area = linkage1->linkage_area;
    
        // Setup call to ffi
        void * prog_linkage_ptr[2];           // Alloc list of pointers for prog linkage
        prog_linkage_ptr[0] = &linkage_area[0];
        prog_linkage_ptr[1] = &linkage_area[1];
    
        call_cobmodule("cob2", 2, prog_linkage_ptr);
    }
    
    int call_cobmodule(char * module, int num_linkage_areas, void ** linkage_areas) {
    
        int rc = cob_call(module, num_linkage_areas, linkage_areas);  
        //rc now holds the result of the call
        return rc;
    }
    

    Output is the same:

    ❯ ./build.sh && LD_LIBRARY_PATH=. COB_LIBRARY_PATH=. ./main
    IN COB1
    COB1-LINKAGE1       
    COB1-LINKAGE2       
    COB1-LINKAGE1       
    IN COB2
    COB1-LINKAGE1       
    libcob: ./cob2.cob:21: error: LINKAGE item 'LINKAGE2' (accessed by 'LINKAGE2-DATA') not passed by caller
    
     Last statement of cob2 was at line 21 of ./cob2.cob
     Last statement of cob1 was at line 24 of ./cob1.cob
    
     
  • A Delosa

    A Delosa - 2022-07-16

    Hi Simon -- Thanks for the pull request. That fixed the issue perfectly..
    Thanks for your time and assistance - it is really appreciated!

     

Anonymous
Anonymous

Add attachments
Cancel