[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [GnuCOBOL-users] Interfacing COBOL with C
From: |
Simon Sobisch |
Subject: |
Re: [GnuCOBOL-users] Interfacing COBOL with C |
Date: |
Sat, 4 Aug 2018 14:34:28 +0200 |
User-agent: |
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 |
Hi Michael,
Am 04.08.2018 um 04:20 schrieb Michael Potter:
> I dug into the cobcrun code and saw they were copying the
> COB_LIBRARY_PATH into a separate environment.
This is only done on cobcrun if you specify a module search path `-M
path`, otherwise not needed.
> I coded that in my .c file _something_ like this:
>
> (void) cob_setenv ("COB_LIBRARY_PATH", getenv("COB_LIBRARY_PATH"), 1);
> (void) cob_setenv ("COB_PRE_LOAD", "UNDATE", 1);
>
> LibHandle = dlopen("MYPROG.so", RTLD_NOW);
>
> cob_init(); // Added per James' suggestion.
>
> ProgramEntry = (ProgramEntryType)dlsym(LibHandle, "MYPROG");
>
> ProgramEntry();
>
> If anyone has a good idea of what I should change please speak up. If I
> don't hear anything I will code up a minimal test case and post it.
Your very first C program will do the setup/cleanup, all others just
resolve the COBOL functions and call them. From the official manual /
info, section "C interface":
#include <libcob.h>
int
main (int argc, char **argv)
{
/* initialize your program */
...
/* initialize the COBOL run-time library */
cob_init (argc, argv);
/* rest of your program */
...
/* Clean up and terminate - This does not return */
cob_stop_run (return_status);
}
You can write cobc_init(0, NULL); if you do not want to pass command
line arguments to COBOL.
If you just want to finish COBOL *completely* use cob_tidy() instead of
cob_stop_run (int).
You can find a COBOL module having a specific name by using the C
function cob_resolve, which takes the module name as a string and
returns a pointer to the module function.
cob_resolve returns NULL if there is no module. In this case, the
function cob_resolve_error returns the error message.
int ret;
char hello[8] = "Hello, ";
char world[7] = "world!";
/* Find the module with PROGRAM-ID "say". */
say = cob_resolve("say");
/* If there is no such module, show error and exit. */
if(say == NULL) {
fprintf(stderr, "%s\n", cob_resolve_error());
exit(1);
}
/* Call the module found ... */
ret = say(hello, world);
/* ...and exit with the return code. */
cob_stop_run(ret);
Exactly 0 dlopen needed (libcob does it for you).
> My code is structured such that c calls COBOL calls c calls COBOL calls
> c ....
Should work fine. For C->COBOL ensure that you match the LINKAGE
exactly. COBOL->C either match directly or use the function set Ron
added for interfacing C with COBOL (needs GnuCOBOL 2.2 or newer).
Using these you won't have to fight with COBOL data types in C and this
works for COBOL -> C and COBOL <- C back.
See libcob/common.h "Functions in move.c for C access to COBOL data" and
Ron's marvelous extra documentation which I attach as I'm not sure if
this was posted here before (a patch for gnucobol.texi to include it
would be welcomed).
Simon
GnuCOBOL C data routines.odt
Description: application/vnd.oasis.opendocument.text