If you are calling COBOL subroutines in Windows, which in turn call C routines, you may want to locate those routines in the calling executable file. You can do this without relinking the runtime by registering your own "sub" function in the C main program. You must add the following declaration to your main program:
typedef int (*ACU_SUB_FUNC)(int argc, char **argv); ACU_SUB_FUNC *acu_register_sub( ACU_SUB_FUNC *pFunc );
The routine acu_register_sub() registers its argument (pFunc) as an additional "sub" function to call. If pFunc is set to NULL, any existing registration is removed.
The registered function is called just like "sub", but it is called before "sub". Note that "sub" is still called if the registered function returns the constant NotFound.
Example
The following C routine calls a COBOL program which, in turn, calls a C program named "MSGBOX":
#include <stdio.h> #include <windows.h> #include "sub.h" extern int __stdcall AcuInitialize( char *cmdLine ); extern void __stdcall AcuShutdown(void); // This is the "sub" function that will be registered int __cdecl local_sub( int argc, char **argv ) { if ( strcmp( argv[0], "MSGBOX" ) == 0 ) { MessageBox( NULL, argv[1], NULL, MB_OK ); return Okay; } return NotFound; } // local_sub int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MessageBox( NULL, "Starting in 'C'", NULL, MB_OK ); // Initialize the runtime using the Visual Basic initializer. // This prevents the runtime from calling exit() when halting. AcuInitialize( "" ); // Install our "sub" handler acu_register_sub( local_sub ); // Call the COBOL program. This one takes no parameters // Assume that this program calls MSGBOX at some point. // MSGBOX is located in "cblprog". It will be found // because "cblprog" got registered with the runtime. struct a_cobol_info cblinfo; memset(&cblinfo, 0, sizeof(cblinfo)); cblinfo.a_cobol_info_size = sizeof(cblinfo); cblinfo.pgm_name = "cblprog"; cblinfo.num_params = 0; cblinfo.params = cblinfo.no_stop = 1; acu_cobol(&cblinfo); // De-initialize the runtime. AcuShutdown(); MessageBox( NULL, "Back in 'C' - finished", NULL, MB_OK ); return 0; }
Here is the COBOL program called above:
program-id. test. working-storage section. 77 message-text pic x(80). procedure division. main-logic. display "In COBOL program". display "Calling MSGBOX" move "This is a message" to message-text inspect message-text replacing trailing spaces by low-values call "MSGBOX" using message-text display "Back from MSGBOX". display "Press enter to execute STOP RUN ", no advancing. accept omitted. stop run.