Calling C ILE Procedure from COBOL 400 Program

185 pts.
Tags:
AS/400 Parameters
COBOL
COBOL/400
ILE Program
I cannot get the parameters correct on this. I created a module for both the C and the COBOL, then used CRTPGM. My COBOL has WS-FIRST-COBOL-NUM PIC S9(2), WS-SECOND-COBOL-NUM PIC S9(2), WS-NUM-TOTAL-COBOL PIC S9(3) defined in WORKING-STORAGE.                Then I use those for my call to the C procedure as: CALL PROCEDURE "TESTC" USING WS-FIRST-COBOL-NUM WS-SECOND-COBOL-NUM WS-NUM-TOTAL-COBOL. In the C program I have the following code: #include [stdio.h][/stdio.h]#include [stdio.h][/stdio.h]void "TESTC"(int num1, int num2, int total) { total = num1 + num2); return; } I display the numbers before the call to (I hardcode them in the COBOL) the C program and after. Before it displays as 08 09 000 and so does after. I know there is something with the call by reference but I cannot figure it out. I tried using *total on the (int *total and *total = num1 + num2). I also tried doing a call to C as a program using void main and doing the call in COBOL as: CALL "TESTC" USING BY REFERENCE WS-FIRST-COBOL-NUM WS-SECOND-COBOL-NUM WS-NUM-TOTAL-COBOL. This just makes it abend. Then I read that you need in the C as: void main(int argc, char * argv[]) but then I didn't understand how you pass the real parms you need. I am new to C and ILE.

Answer Wiki

Thanks. We'll let you know when a new response is added.

Skill wise I am an OPM COBOL/400 programmer. Our shop does not use COBOL ILE at all so I am trying to figure out the approach. The ultimate goal is to eventually have a COBOL program that calls a C program that eventually goes out to a web service. For now, I am working on (as my original example was trying to explain poorly, I’m new) a proof of concept to create a COBOL ILE program call a C ILE procedure. I do not want to create a C program, just a C procedure. My COBOL ILE module has the following.

MOVE 8 TO WS-FIRST-COBOL-NUM
MOVE 9 TO WS-SECOND-COBOL-NUM

WS-FIRST-COBOL-NUM PIC S9(02).
WS-SECOND-COBOL-NUM PIC S9(02).
WS-NUM-TOTAL-COBOL PIC S9(02).

CALL PROCEDURE “SHARETEST3″ USING WS-FIRST-COBOL-NUM
WS-SECOND-COBOL-NUM
WS-NUM-TOTAL-COBOL.

———————————————————————————-

Here is my C procedure logic:

#include <stdio.h>
#include <stdlib.h>
void SHARETEST3(int num1, int num2, int total)
{
total = num1 + num2;
return;
}

——————————————————————————-
I put displays in the COBOL program:

DISPLAY ‘BEFORE CALL TO C ‘ WS-FIRST-COBOL-NUM
‘*’ WS-SECOND-COBOL-NUM
‘*’ WS-NUM-TOTAL-COBOL.

CALL PROCEDURE “TESTC” USING WS-FIRST-COBOL-NUM
WS-SECOND-COBOL-NUM
WS-NUM-TOTAL-COBOL.
DISPLAY ‘AFTER CALL TO C ‘ WS-FIRST-COBOL-NUM
‘*’ WS-SECOND-COBOL-NUM
‘*’ WS-NUM-TOTAL-COBOL.

The result is exactly the same before and after the call: 08*09*000

I thought that the argc and argv[ ] were only if you were to create a C ILE program. The C ILE procedure is how I am going to do this. I will create my COBOL ILE module, the C ILE module and then do CRTPGM to make a runnable object.

Also, ultimately I would need this calling chain – OPM COBOL calls ILE CRTGM object. so, this would be OPM COBOL ==> ILE CRTPGM (inside is the COBOL ILE mod and the C ILE mod). Is it possible to do this; calling an ILE program from an OPM COBOL?

To answer your questions Tom, I want a C procedure. I need the result in a returned value. On a side note I’d rather learn C but I primarily know COBOL. Because we will be trying, later on, to do web servcie calls, I need to do the COBOL to the C. I am with you on the learning curve. I’m learning ILE and C.

Thank you very much for your input. I have to see why that WS-NUM-TOTAL-COBOL is not working correctly.

Discuss This Question: 9  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • TomLiotta
    ...you need in the C as: void main(int argc, char * argv[])... That's a little odd for a C proc that will work with three "numeric" arguments, but it's not odd for a lot of C programmers to do it that way for a C program. That's also how IBM tends to document main() procedure prototypes for C programs. This part -- int argc -- is related to the C program finding out how many arguments came into the program. This part -- char * argv[] -- is saying that the argument list will be an array of pointers to memory defined as "char". For a C procedure (rather than a C program), you might find other prototypes a little easier. Even for a C program, the prototype you showed requires some work in C to get the addresses to give your program reasonable "numeric" values. Somewhere early in the C program, there will likely be a couple of assignment statements that will cast argv[1] and argv[2] to more common numeric C datatypes, probably int. And towards the end, the result of any addition will be placed into argv[3] in order to get the result back into the calling program. However, you asked about C procedures rather than C programs. It is likely that you will want to use a prototype that is different from what you showed. It might look something like this:
    int addnbrs(int *, int *)
    ...or perhaps even:
    int addnbrs( int, int )
    In those cases, the value is 'returned' by the procedure. That's a little different from being stored in a argument. If you really want the proc to place the result value into the third parameter in your COBOL procedure rather than simply returning it, then the prototype might look this way:
    void addnbrs(int *, int *, int *)
    ...or:
    void addnbrs( int, int, int * )
    In all of those, the name of the C proc is 'addnbrs'. The COBOL CALL would look a little different for each one, but they're all fairly easy. Before actually choosing the COBOL format, let's make sure that you have it clear which way it will be done. First, do you want to call a C program or a C procedure? A C procedure will be bound with your COBOL procedure in order to create a single program object that will contain both of them. A C program will be created completely separately from any COBOL program that might call it. Making external program calls is not the same as making bound procedure calls. A procedure would be easiest. Then, is it a requirement to send the result back in a parameter or can it simply be a turned value? If a returned value is used, you would need to create a C procedure rather than a C program. But a parameter can carry the result out of a program or a procedure -- it's just a value in a memory address either way. Returning the result as a return value is probably easiest. Finally, is it more important for you to learn C or COBOL? Instead of COBOL, the CALL could be made from CL or RPG or even C. The principles would be pretty much the same for any of those and the coding in each of those could be recognizable whether a program or a proc was being called. But the coding of C can be very different depending on exactly what you're trying to build. C tends to have a lot of ugly variations that can obscure some of the simplest things. If you are trying to "learn" C while simultaneously learning ILE conventions, the learning tasks are more complicated. See if you can state the problem in terms of the three questions that I asked. There could be a lot of content that can be skipped over depending on what you're really needing to learn. Tom
    125,585 pointsBadges:
    report
  • carlosdl
    If it is a C procedure, it should be declared this way:
    void TESTC (int num1, int num2, int &total)
    69,920 pointsBadges:
    report
  • carlosdl
    Or at least, that is how it should be declared if it were going to be called from another C routine. I don't know if something changes when COBOL is involved.
    69,920 pointsBadges:
    report
  • TomLiotta
    void TESTC (int num1, int num2, int &total) That's valid and should be added to the variations. It adds a little complexity to discussion. We have code using both. But I'm hoping to get some dialog about just what is needed. I suspect 400Programme is feeling lost and doesn't know how to respond. We can guide discussion if it gets going, but until then...? Tom
    125,585 pointsBadges:
    report
  • 400Programmer
    Skill wise I am an OPM COBOL/400 programmer. Our shop does not use COBOL ILE at all so I am trying to figure out the approach. The ultimate goal is to eventually have a COBOL program that calls a C program that eventually goes out to a web service. For now, I am working on (as my original example was trying to explain poorly, I'm new) a proof of concept to create a COBOL ILE program call a C ILE procedure. I do not want to create a C program, just a C procedure. My COBOL ILE module has the following. MOVE 8 TO WS-FIRST-COBOL-NUM MOVE 9 TO WS-SECOND-COBOL-NUM WS-FIRST-COBOL-NUM PIC S9(02). WS-SECOND-COBOL-NUM PIC S9(02). WS-NUM-TOTAL-COBOL PIC S9(02). CALL PROCEDURE "SHARETEST3" USING WS-FIRST-COBOL-NUM WS-SECOND-COBOL-NUM WS-NUM-TOTAL-COBOL. ---------------------------------------------------------------------------------- Here is my C procedure logic: #include <stdio.h> #include <stdlib.h> void SHARETEST3(int num1, int num2, int total) { total = num1 + num2; return; } ------------------------------------------------------------------------------- I put displays in the COBOL program: DISPLAY 'BEFORE CALL TO C ' WS-FIRST-COBOL-NUM '*' WS-SECOND-COBOL-NUM '*' WS-NUM-TOTAL-COBOL. CALL PROCEDURE "TESTC" USING WS-FIRST-COBOL-NUM WS-SECOND-COBOL-NUM WS-NUM-TOTAL-COBOL. DISPLAY 'AFTER CALL TO C ' WS-FIRST-COBOL-NUM '*' WS-SECOND-COBOL-NUM '*' WS-NUM-TOTAL-COBOL. The result is exactly the same before and after the call: 08*09*000 I thought that the argc and argv[ ] were only if you were to create a C ILE program. The C ILE procedure is how I am going to do this. I will create my COBOL ILE module, the C ILE module and then do CRTPGM to make a runnable object. Also, ultimately I would need this calling chain - OPM COBOL calls ILE CRTGM object. so, this would be OPM COBOL ==> ILE CRTPGM (inside is the COBOL ILE mod and the C ILE mod). Is it possible to do this; calling an ILE program from an OPM COBOL? To answer your questions Tom, I want a C procedure. I need the result in a returned value. On a side note I'd rather learn C but I primarily know COBOL. Because we will be trying, later on, to do web servcie calls, I need to do the COBOL to the C. I am with you on the learning curve. I'm learning ILE and C. Thank you very much for your input. I have to see why that WS-NUM-TOTAL-COBOL is not working correctly.
    185 pointsBadges:
    report
  • 400Programmer
    I have a mistake. In my code I wrote CALL PROCEDURE “TESTC” USING WS-FIRST-COBOL-NUM. I should have written CALL PROCEDURE “SHARETEST3” USING WS-FIRST-COBOL-NUM. Also, in the beginning i wrote 'The ultimate goal is to eventually have a COBOL program that calls a C program', I should have wrote The ultimate goal is to eventually have a COBOL program that calls a C procedure'.
    185 pointsBadges:
    report
  • 400Programmer
    I got it to work finally. Here is what I did. WORKING-STORAGE SECTION. 01 WS-NUM1 PIC S9(04) COMP-4. 01 WS-NUM2 PIC S9(04) COMP-4. 01 WS-NUM-TOTAL PIC S9(04) COMP-4. MOVE 8 TO WS-NUM1. MOVE 9 TO WS-NUM1. MOVE 0 TO WS-NUM-TOTAL. CALL PROCEDURE "TESTC" USING BY VALUE WS-NUM1 BY VALUE WS-NUM2 RETURNING WS-NUM-TOTAL. Then the TESTC program: short TESTC(short in1, short in2) { return (in1 + in2); } In the COBOL program I wrote the three fields to an externally described PF file: R TESTR NUM1 2S 0 NUM2 2S 0 TOTAL 3S 0 Thanks everyone for your help. My problem was the data compatability. WRKQRY on the output file revealed the results finally. 8 9 17.
    185 pointsBadges:
    report
  • carlosdl
    Glad it worked. However, I would recommend trying to make it work without changing the way you return the total from the C procedure (which you converted into a function), as you might need to do something similar in the future.
    69,920 pointsBadges:
    report
  • TomLiotta
    The code is very close. Here's your original C code:
    #include <stdio.h>
    #include <stdlib.h>
    void SHARETEST3(int num1, int num2, int total)
    {
    total = num1 + num2;
    return;
    }
    Make this change first:
    void SHARETEST3(int num1, int num2, int *total)
    That changes total from an integer that was passed in by value to a pointer to an integer. The pointer will be passed as the address of the variable back in the COBOL program. You have to pass in the address of that variable because that will be how the C procedure will be able to change it. If all C has is the value of the variable, there's no way that the value will be seen back in the COBOL procedure. And to complete the change:
     *total = num1 + num2;
    That tells C to store the result back at the address pointed to by "*total". And because the prototype says that the pointer points to storage defined as an int, that's how the value will be formatted in memory when the COBOL code starts to run again. I can't tell if the COBOL program is totally correct since it's not all shown. But the procedure call would look like:
    CALL PROCEDURE “TESTC” USING
              by value  WS-FIRST-COBOL-NUM
              by value  WS-SECOND-COBOL-NUM
              by reference  WS-NUM-TOTAL-COBOL.
    Note that "BY REFERENCE" must be specified for the third parameter. That's because even though "BY REFERENCE" is the 'default', it's only the default until you specify something else. When you specify "BY VALUE", that becomes the default for everything that follows -- until you change it. If you never specify anything, it'll be "BY REFERENCE". But whenever you put something else, the default changes. (I hope that makes sense.) Basically, you had it almost done with a COBOL module and a C module bound into a single program object. COBOL would call a procedure in the C module, and the result would appear back in COBOL. Just a couple minor technical details. Tom
    125,585 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following