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.