Discussion:
AS400 C++ calling COBOL - MCH0802
(too old to reply)
s***@kiska.net
2013-05-06 19:36:46 UTC
Permalink
Hi Gurus,

Here is the problem:

1. I have ILE COBOL program (*PGM) with let say 3 parameter
2. I am calling this program (dynamically) from other COBOL program let say
with 5 parameters - call is going thru, everything is okay.
3. I need to do the same call from C++ - I am getting MCH0802 (number of
parameters mismatch).

What is wrong and how to avoid that ?

Regards,
Sergey

-------------- CALLEE.CBL ------------
IDENTIFICATION DIVISION.
PROGRAM-ID. CALLEE.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 P1 PIC X(5).
01 P2 PIC X(5).
01 P3 PIC X(5).
PROCEDURE DIVISION USING P1 P2 P3.
0000-MAIN.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
MOVE 'RET1' TO P1.
MOVE 'RET2' TO P2.
MOVE 'RET3' TO P3.
GOBACK.
--------------------------- CBCALLER.CBL -----------------
IDENTIFICATION DIVISION.
PROGRAM-ID. CALLER.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 P1 PIC X(5) VALUE 'PARM1'.
01 P2 PIC X(5) VALUE 'PARM2'.
01 P3 PIC X(5) VALUE 'PARM3'.
01 P4 PIC X(5) VALUE 'PARM4'.
01 P5 PIC X(5) VALUE 'PARM5'.
01 SUB PIC X(8) VALUE 'CALLEE'.
PROCEDURE DIVISION.
0000-MAIN.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
DISPLAY 'P4=' P4 ';'.
DISPLAY 'P5=' P5 ';'.
DISPLAY 'CALL CALLEE'.
CALL SUB USING P1 P2 P3.
DISPLAY 'RETURN FROM CALLEE'.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
DISPLAY 'P4=' P4 ';'.
DISPLAY 'P5=' P5 ';'.
GOBACK.
---------------------- CALLER.CPP ----------------------------
#include <miptrnam.h>
#include <except.h>
#include <stdio.h>

static char p1[6] = "parm1";
static char p2[6] = "parm2";
static char p3[6] = "parm3";
static char p4[6] = "parm4";
static char p5[6] = "parm5";

extern "OS" typedef void (OS_fct_t) (...);

int main(int argc, char * argv[])
{
OS_fct_t * os_fct_ptr;
#pragma exception_handler(Lnone, 0, _C1_ALL, _C2_ALL, _CTLA_HANDLE_NO_MSG)
os_fct_ptr = (OS_fct_t *) rslvsp(_Program, "CALLEE", "*LIBL",
_AUTH_OBJ_MGMT);
printf("Calling CALLEE with %s, %s, %s, %s, %s\n", p1, p2, p3, p4, p5);
os_fct_ptr(p1, p2, p3, p4, p5);
printf("CALLEE returned %s, %s, %s, %s, %s\n", p1, p2, p3, p4, p5);
return 0;
Lnone:
#pragma disable_handler
printf("Non-Resolved\n");
return 0;
}
----------------------------------------------
d***@panix.com
2013-05-07 14:08:02 UTC
Permalink
Post by s***@kiska.net
Hi Gurus,
No 'hi' for me?
Post by s***@kiska.net
1. I have ILE COBOL program (*PGM) with let say 3 parameter
2. I am calling this program (dynamically) from other COBOL program let say
with 5 parameters - call is going thru, everything is okay.
3. I need to do the same call from C++ - I am getting MCH0802 (number of
parameters mismatch).
What is wrong and how to avoid that ?
First of all... the AS400 was renamed to the eServer iSeries about a
decade ago. Using an obsolete name increases the billing-rate by 37.2%.

Brute-force approach: change the parameter-list in the CALLed program a
few times for testing.

Might help if the application was mentioned... is this for insurance,
inventory, industry or investing?

DD
s***@kiska.net
2013-05-07 22:29:00 UTC
Permalink
Post by d***@panix.com
First of all... the AS400 was renamed to the eServer iSeries about a
Hi DD,

Secondly AS400 does not exist as a hardware anymore, etc, etc. I know.
Post by d***@panix.com
decade ago. Using an obsolete name increases the billing-rate by 37.2%.
And 50% more for using obsolete technologies, like COBOL, etc :-))
Post by d***@panix.com
Brute-force approach: change the parameter-list in the CALLed program a
few times for testing.
That's not what I was asking. The question was specific.
Post by d***@panix.com
Might help if the application was mentioned... is this for insurance,
inventory, industry or investing?
Does not matter.

Regards,
SKA
d***@panix.com
2013-05-08 16:51:14 UTC
Permalink
[snip]
Post by s***@kiska.net
Post by d***@panix.com
Brute-force approach: change the parameter-list in the CALLed program a
few times for testing.
That's not what I was asking. The question was specific.
The question was 'What is wrong and how to avoid that ?'

The answer is 'The parameter expectations and do it correctly.'
Post by s***@kiska.net
Post by d***@panix.com
Might help if the application was mentioned... is this for insurance,
inventory, industry or investing?
Does not matter.
If only you knew the other answer as certainly!

DD
s***@kiska.net
2013-05-09 19:09:17 UTC
Permalink
Post by d***@panix.com
Post by d***@panix.com
Brute-force approach: change the parameter-list in the CALLed program a
few times for testing.
The answer is 'The parameter expectations and do it correctly.'
Thanks, DD !

You were as usually right, and that was my stupidity :-(

As for the solution, the only I've found is to do something like that:
Qcl_PGMI0100_t info;
Qus_EC_t error_code;
error_code.Bytes_Provided = 0;
QCLRPGMI(&info, sizeof(info), "PGMI0100", "CALLEE *LIBL ", &error_code);

and than figuring out the number of parameters, do a huge case:

if(info.Max_Parameters == 3) {
epgm(p1, p2, p3);
} else if(info.Max_Parameters == 4) {
epgm(p1, p2, p3, p4);
} else {
epgm(p1, p2, p3, p4, p5); // etc
}

Regards,
SKA
d***@panix.com
2013-05-09 19:29:30 UTC
Permalink
Post by s***@kiska.net
Post by d***@panix.com
Post by d***@panix.com
Brute-force approach: change the parameter-list in the CALLed program a
few times for testing.
The answer is 'The parameter expectations and do it correctly.'
Thanks, DD !
You were as usually right, and that was my stupidity :-(
I know the answers to some of the errors I've made, at times. Now the
burden is on you to assist others as you've been assisted.

DD

j***@hotmail.com
2013-05-07 21:27:18 UTC
Permalink
Post by s***@kiska.net
Hi Gurus,
1. I have ILE COBOL program (*PGM) with let say 3 parameter
2. I am calling this program (dynamically) from other COBOL program let say
with 5 parameters - call is going thru, everything is okay.
3. I need to do the same call from C++ - I am getting MCH0802 (number of
parameters mismatch).
What is wrong and how to avoid that ?
Regards,
Sergey
-------------- CALLEE.CBL ------------
IDENTIFICATION DIVISION.
PROGRAM-ID. CALLEE.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 P1 PIC X(5).
01 P2 PIC X(5).
01 P3 PIC X(5).
PROCEDURE DIVISION USING P1 P2 P3.
0000-MAIN.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
MOVE 'RET1' TO P1.
MOVE 'RET2' TO P2.
MOVE 'RET3' TO P3.
GOBACK.
--------------------------- CBCALLER.CBL -----------------
IDENTIFICATION DIVISION.
PROGRAM-ID. CALLER.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 P1 PIC X(5) VALUE 'PARM1'.
01 P2 PIC X(5) VALUE 'PARM2'.
01 P3 PIC X(5) VALUE 'PARM3'.
01 P4 PIC X(5) VALUE 'PARM4'.
01 P5 PIC X(5) VALUE 'PARM5'.
01 SUB PIC X(8) VALUE 'CALLEE'.
PROCEDURE DIVISION.
0000-MAIN.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
DISPLAY 'P4=' P4 ';'.
DISPLAY 'P5=' P5 ';'.
DISPLAY 'CALL CALLEE'.
CALL SUB USING P1 P2 P3.
DISPLAY 'RETURN FROM CALLEE'.
DISPLAY 'P1=' P1 ';'.
DISPLAY 'P2=' P2 ';'.
DISPLAY 'P3=' P3 ';'.
DISPLAY 'P4=' P4 ';'.
DISPLAY 'P5=' P5 ';'.
GOBACK.
---------------------- CALLER.CPP ----------------------------
#include <miptrnam.h>
#include <except.h>
#include <stdio.h>
static char p1[6] = "parm1";
static char p2[6] = "parm2";
static char p3[6] = "parm3";
static char p4[6] = "parm4";
static char p5[6] = "parm5";
extern "OS" typedef void (OS_fct_t) (...);
int main(int argc, char * argv[])
{
OS_fct_t * os_fct_ptr;
#pragma exception_handler(Lnone, 0, _C1_ALL, _C2_ALL, _CTLA_HANDLE_NO_MSG)
os_fct_ptr = (OS_fct_t *) rslvsp(_Program, "CALLEE", "*LIBL",
_AUTH_OBJ_MGMT);
printf("Calling CALLEE with %s, %s, %s, %s, %s\n", p1, p2, p3, p4, p5);
os_fct_ptr(p1, p2, p3, p4, p5);
printf("CALLEE returned %s, %s, %s, %s, %s\n", p1, p2, p3, p4, p5);
return 0;
#pragma disable_handler
printf("Non-Resolved\n");
return 0;
}
----------------------------------------------
Your CALLEE has three parameters and is called with three parameters in CALLER.
The C++ tries to call CALLEE with 5 parameters.

If you change the C++ to call CALLER instead of CALLEE or change it to call CALLEE with three parameters, things will probably work.
s***@kiska.net
2013-05-07 22:38:03 UTC
Permalink
Post by j***@hotmail.com
Your CALLEE has three parameters and is called with three parameters in CALLER.
The C++ tries to call CALLEE with 5 parameters.
Hi John,
It looks I knew that from the beginning :-)
Post by j***@hotmail.com
If you change the C++ to call CALLER instead of CALLEE or change it to call CALLEE with three parameters, things will probably work.
I just wanted to avoid the call to intermediate COBOL PGM if possible, as the number of parameters is not known upfront. Otherwise I might end up with 50 or more parameters intermediate COBOL program.
If "COBOL call COBOL" does not give any excaptions than it should be the way to do "C++ call COBOL" exactly the same way, maybe calling appropriate API.

Regards,
Sergey
JohnM
2013-05-08 08:19:25 UTC
Permalink
Post by s***@kiska.net
Post by j***@hotmail.com
Your CALLEE has three parameters and is called with three parameters in CALLER.
The C++ tries to call CALLEE with 5 parameters.
Hi John,
It looks I knew that from the beginning :-)
Post by j***@hotmail.com
If you change the C++ to call CALLER instead of CALLEE or change it to call CALLEE with three parameters, things will probably work.
I just wanted to avoid the call to intermediate COBOL PGM if possible, as the number of parameters is not known upfront. Otherwise I might end up with 50 or more parameters intermediate COBOL program.
If "COBOL call COBOL" does not give any excaptions than it should be the way to do "C++ call COBOL" exactly the same way, maybe calling appropriate API.
Regards,
Sergey
Hi Sergey,

what I was trying to say is that the COBOL doesn't call CALLEE with
more than the expected number of parameters - did you mean to call
CALLEE with 5 parameters from CALLER?

Regards,
John
s***@kiska.net
2013-05-08 11:53:58 UTC
Permalink
Post by j***@hotmail.com
Your CALLEE has three parameters and is called with three parameters in CALLER.
Thanks, John !!!
Probably I was working too much - was playing with 3-5 parms on a different platforms and missed that.
That mean it is even worse - COBOL to COBOL also giving exception.
Don't know how to disable this dumb parameters check :-(

Regards,
Sergey
Loading...