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