Hi again,
Hoping you can help me get C to COBOL to C linkages working. I am having some challenges, have tried lots of things and still have no idea where the issue is.
I have simplified and recreated the issue in the above GitHub repo.
It also has some explanations on what I am trying to do.
I can't work out why the parameter parsing works on the first C->COBOL call but on the subsequent call (C->COBOL-C->COBOL) it says that the second linkage area has not been passed.. but I have.. And I can't work it out because the first linkage area is fine and I use the same process for both.
I suspect its just my bad programming.. but I just can't see it.
Any pointers would be appreciated. Feel free to ask any questions..
Anthony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Found what should be in the Manual included in the testsuite. Using your original program and GnuCOBOL 3 your "C2" program must explicit tell the COBOL runtime that it did not get the same number of parameters that were used in the last COBOL CALL.
To do so:
cob_get_global_ptr()->cob_call_params=2;
We still should have a look at your second example.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For this scenario the easiest setup would be to use cob_call, but this does not seem to be possible directly as you want to use it with a function pointer.
In this case - using GnuCOBOL 3 - the easiest option is to use a C wrapper passing that's function pointer - and from there use cob_call.
Background: first COBOL module "sees" that there is no COBOL in stack and internally sets the number of linkage arguments depending on "not null", then it does a CALL and in there sets "I pass only 1 argument", then C comes, calls the second COBOL program which sees COBOL in stack and then takes "there was one item used for CALL".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Simon -- thanks for the response. From what I can tell the cob_call function has the same signature as my call_cobmodule function.
I replaced the call but I get the same outcome.. Have I understood what you are saying correctly or am I not using cob_call correctly..
The following is my changes to ccall.c
#include<ffi.h>#include<libcob.h>#include<stdio.h>staticvoid(*cobmodule)(void);intcall_cobmodule(char*module,intnum_linkage_areas,void**linkage_areas);structlinkage1{void*linkage_area;// pointer linkage_areachardata[20];// tran number (FW)};voidccall(structlinkage1*linkage1){printf("%s\n",linkage1->data);void**linkage_area=linkage1->linkage_area;// Setup call to ffivoid*prog_linkage_ptr[2];// Alloc list of pointers for prog linkageprog_linkage_ptr[0]=&linkage_area[0];prog_linkage_ptr[1]=&linkage_area[1];call_cobmodule("cob2",2,prog_linkage_ptr);}intcall_cobmodule(char*module,intnum_linkage_areas,void**linkage_areas){intrc=cob_call(module,num_linkage_areas,linkage_areas);//rc now holds the result of the callreturnrc;}
Output is the same:
❯ ./build.sh && LD_LIBRARY_PATH=. COB_LIBRARY_PATH=. ./main
IN COB1
COB1-LINKAGE1
COB1-LINKAGE2
COB1-LINKAGE1
IN COB2
COB1-LINKAGE1
libcob: ./cob2.cob:21: error: LINKAGE item 'LINKAGE2' (accessed by 'LINKAGE2-DATA') not passed by caller
Last statement of cob2 was at line 21 of ./cob2.cob
Last statement of cob1 was at line 24 of ./cob1.cob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi again,
Hoping you can help me get C to COBOL to C linkages working. I am having some challenges, have tried lots of things and still have no idea where the issue is.
https://github.com/adelosa/gnucob-ffi
I have simplified and recreated the issue in the above GitHub repo.
It also has some explanations on what I am trying to do.
I can't work out why the parameter parsing works on the first C->COBOL call but on the subsequent call (C->COBOL-C->COBOL) it says that the second linkage area has not been passed.. but I have.. And I can't work it out because the first linkage area is fine and I use the same process for both.
I suspect its just my bad programming.. but I just can't see it.
Any pointers would be appreciated. Feel free to ask any questions..
Anthony
Found what should be in the Manual included in the testsuite. Using your original program and GnuCOBOL 3 your "C2" program must explicit tell the COBOL runtime that it did not get the same number of parameters that were used in the last COBOL
CALL.To do so:
We still should have a look at your second example.
Sorry.. forgot to log in before positing.. It's me!
Please have a look at "C interface" in the GnuCOBOL manual, source and generated PDF.
Hm, that was less helpful than I've thought.
For this scenario the easiest setup would be to use
cob_call, but this does not seem to be possible directly as you want to use it with a function pointer.In this case - using GnuCOBOL 3 - the easiest option is to use a C wrapper passing that's function pointer - and from there use
cob_call.Background: first COBOL module "sees" that there is no COBOL in stack and internally sets the number of linkage arguments depending on "not null", then it does a CALL and in there sets "I pass only 1 argument", then C comes, calls the second COBOL program which sees COBOL in stack and then takes "there was one item used for CALL".
Hi Simon -- thanks for the response. From what I can tell the
cob_callfunction has the same signature as mycall_cobmodulefunction.I replaced the call but I get the same outcome.. Have I understood what you are saying correctly or am I not using cob_call correctly..
The following is my changes to
ccall.cOutput is the same:
Hi Simon -- Thanks for the pull request. That fixed the issue perfectly..
Thanks for your time and assistance - it is really appreciated!