Skip to main content

Problem:

Example of how to implement a COBOL Callback method that is called from C

Resolution:

2 example programs are shown below:

callbacks.cbl

       identification division.

       program-id. callbacks.

       data division.

       working-storage section.

       01 pptr-callback1        procedure-pointer.

       01 pptr-callback2        procedure-pointer.

       01 pptr-C-DLL            procedure-pointer value null.

       01 callback-id           pic 9(9) comp-5.

       01 char-count            pic 9(9) comp-5.

       01 junk                  pic x.

       local-storage section.

       linkage section.

       01 an-integer            pic 9(9) comp-5.

       01 a-string              pic x(35).

       procedure division.

           set pptr-callback1 to entry "callback1".

           set pptr-callback2 to entry "callback2".

           set pptr-C-DLL      to entry "subprogC.dll"

           if pptr-C-DLL = null

              display "subprogC.dll not loaded"

              display "Hit Enter to end..."

              accept junk

              stop run

           end-if.

           move 0 to callback-id.

           call "InitCallback" using by value callback-id

                                      by value pptr-callback1.

           move 1 to callback-id.

           call "InitCallback" using by value callback-id

                                      by value pptr-callback2.

           move 2 to callback-id.

           call "InitCallback" using by value callback-id

                                      by value pptr-callback1.

           move 0 to callback-id.

           call "DoCallback" using by value callback-id.

           move 1 to callback-id.

           call "DoCallback" using by value callback-id.

           move 2 to callback-id.

           call "DoCallback" using by value callback-id.

           display "Hit Enter to end...".

           accept junk.

           stop run.

       entry "callback1" using  by value an-integer

                                by reference a-string.

           move 0 to char-count.

           inspect a-string tallying char-count

              for characters before x"00".

           display "callback1 called with parameter:".

           display "  an-integer " an-integer.

           display "  a-string   " a-string(1:char-count).

           exit program.

       entry "callback2" using by value an-integer

                               by reference a-string.

           move 0 to char-count.

           inspect a-string tallying char-count

              for characters before x"00".

           display "callback2 called with parameter:".

           display "  an-integer " an-integer.

           display "  a-string   " a-string(1:char-count).

           exit program.

subprogC.c

/* build with Visual C 6.0: cl /LD subprogC.c  */

#ifdef __cplusplus

extern "C"   {

#endif

int gNumberCallbacks = 0;

typedef void (*pf)(unsigned int, char*);

pf pf1;

struct callbackStruct {

    unsigned int callbackID;

    pf  callbackPPtr;

    char callbackMessage[35];    

};

struct callbackStruct cb[10];

__declspec(dllexport) void InitCallback (unsigned int id, pf pfp) {

     

    extern struct callbackStruct cb[10];   

    if (id >= 0 && id < 10) {

        cb[id].callbackID = id;

        cb[id].callbackPPtr = pfp;

        sprintf(cb[id].callbackMessage, "C Callback message for ID %d", id);

    }    

        

}

__declspec(dllexport) void DoCallback (unsigned int i) {

    extern struct callbackStruct cb[10];

    if (i >= 0 && i < 10)

        cb.callbackPPtr(cb.callbackID, cb.callbackMessage);

}

#ifdef __cplusplus

}  /*extern "C" */

#endif

Old KB# 3943