Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Calling a COBOL programm via C

56 views
Skip to first unread message

christi...@gmail.com

unread,
Dec 7, 2006, 5:56:25 AM12/7/06
to
Hello,

I'm programming on a v5r3 system and have to call a COBOL program from
within C. The problem is that the parameter (LINKAGE SECTION) of the
called programm is defined as "COPY DDS-ALL-FORMATS OF FOOBAR". So my
question is if this is possible at all and if so, how can this be done?

Best regards, Chris Mager.

walker.l2

unread,
Dec 7, 2006, 6:19:11 AM12/7/06
to
I'm a COBOL guy, not a C guy; I'm afraid I don't understand what your
difficulty is though. Can't C use copybooks?

christi...@gmail.com

unread,
Dec 7, 2006, 6:40:16 AM12/7/06
to
Hi,

thanks for your reply!

walker.l2 schrieb:


> I'm a COBOL guy, not a C guy; I'm afraid I don't understand what your
> difficulty is though. Can't C use copybooks?

Well, to call other programms in C you're using the system() function.
This one takes a single parameter where you put the command as is, for
example:
system( "CRTDTAARA ....... ");

But if the called program takes "structured parameter" (like copy
dds-all-formats) system() won't work so I actually have two problems:

- How to get the data definition of db-table FOOBAR into C so that i
get a variable with this structure, and (the main problem)
- how to give this to the called cobol program as a parameter

At the moment I'm searching in the IBM iSeries Information Center for
v5r3, but haven't found some suitable information about that.

Karl Hanson

unread,
Dec 7, 2006, 7:56:06 AM12/7/06
to

See Chapt 18 of the ILE C/C++ Programmer's Guide:
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/books/sc092712.pdf
For external file data definitions, it looks like #pragma mapinc() applies.

See Chapt 25 for info about inter-program linkages. If calling a
separate program (*PGM), it looks like #pragma linkage with the OS
option may apply.

--
Karl Hanson

Christian Mager

unread,
Dec 7, 2006, 8:37:59 AM12/7/06
to
Karl Hanson schrieb:

> See Chapt 18 of the ILE C/C++ Programmer's Guide:
> http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/books/sc092712.pdf
> For external file data definitions, it looks like #pragma mapinc() applies.
>
> See Chapt 25 for info about inter-program linkages. If calling a
> separate program (*PGM), it looks like #pragma linkage with the OS
> option may apply.

hm, yes that seems to be the right information i was searching. I'll
try it and in some days i'll give a statement if it worked or if i have
further questions.

Thanks a lot! Chris Mager.

peter

unread,
Dec 7, 2006, 10:11:09 AM12/7/06
to
christi...@gmail.com wrote:
> Hi,
>
> thanks for your reply!
>
> walker.l2 schrieb:
>> I'm a COBOL guy, not a C guy; I'm afraid I don't understand what your
>> difficulty is though. Can't C use copybooks?
>
> Well, to call other programms in C you're using the system() function.
> This one takes a single parameter where you put the command as is, for
> example:
> system( "CRTDTAARA ....... ");

i am no cobol programmer but in C you can also use fork() and exec*().
they can seem difficult, but write a tiny proc that says "Hello World
From the Parent" and "Hello World From the Child" to start. build upon
that,
hth,
peter

Elvis

unread,
Dec 7, 2006, 12:10:58 PM12/7/06
to
Here's a working example I have:

#pragma linkage (QCMDEXC,OS,nowiden)
void QCMDEXC(char *, decimal(15,5));

Prototype is not necessary, but sure helps C folks understand this
better. Once declared like this, you simply call the program like any
other function:

decimal(15,5) len;
char cmd[100];
strcpy(cmd,"DSPJOB OUTPUT(*PRINT)");
len = strlen(cmd);
QCMDEXC(cmd,len);

As for pulling in file's data structure, you can do it with mapinc
pragma, or even better, GENCSRC CL command can generate all file
includes you need.

system() function is another option, but it won't let you pass non-char
parms easily.

HTH

Elvis

P. Raulerson

unread,
Dec 7, 2006, 9:15:10 PM12/7/06
to
Why won't pragma mapinc followed by an include work for you? Are you doing
something unsual? You are in ILE I am sure.

i.e. (from the manual)
#pragma mapinc("tempname","EXAMPLE/TEST(FMT)","input","d",,"")
#include "tempname"

<christi...@gmail.com> wrote in message
news:1165491616....@f1g2000cwa.googlegroups.com...

Christian Mager

unread,
Dec 8, 2006, 2:22:49 AM12/8/06
to
Hi,

thanks for all your replies. Karls's tip usig #pragma linkage and
mapinc works fine, I just have a problem now that the called program
ends in a MCH1202 error. I have to find out why that happens, but
currently I don't really have time for that.

P. Raulerson schrieb:


> Why won't pragma mapinc followed by an include work for you?

Well, I didn't know about that. I haven't really programed C on an
as400 (but on other systems/OSs of course) before so I still have to
find out some things.

Thx, Chris.

Christian Mager

unread,
Dec 8, 2006, 7:27:21 AM12/8/06
to
ok, I had some tries now. What I forgot to tell is that most of the
fields of the table can have NULL-values. My Code looks approximately
like this:

#pragma mapinc("evlogfmt","LIB/FILE(FMT)","input nullflds","_P d")
#include "evlogfmt"

and

CALLED_PGM( FIL_FILE_FMT_i_t * );
#pragma linkage( CALLED_PGM, OS, nowiden )

that gives me the two structs LIB_FILE_FMT_i_t and LIB_FILE_FMT_nmap_t.
In the *_nmap_t struct I set the null-capable fields to '1' but now I
have no clue what to do with this structure? I think that would solve
my MCH1202-problem.

Thx, Chris.is.

Karl Hanson

unread,
Dec 8, 2006, 10:23:40 AM12/8/06
to

You should be able to use a debugger to see what data is being passed in
from the C program. You didn't say whether the COBOL program is ILE or
OPM, but if ILE you could either use the green screen (STRDBG) or the
System (Graphical) Debugger (I prefer the latter - here's a link I found
via Google:)
www.metromidrange.org/iSeries%20GUI%20Debugger.ppt

Also after getting the MCH1202, you could see low level message details
(F1+F9 on a green screen) to get the "To program" and statement within
it that incurs the MCH1202. My guess would be the COBOl program is
expecting one or more packed decimal and/or zoned decimal fields in the
structure(s), and the C program is not passing valid packed/zoned data
in the field(s).

--
Karl Hanson

Christian Mager

unread,
Dec 8, 2006, 10:45:57 AM12/8/06
to
Hi,

> You should be able to use a debugger to see what data is being passed in
> from the C program. You didn't say whether the COBOL program is ILE or
> OPM, but if ILE you could either use the green screen (STRDBG) or the
> System (Graphical) Debugger (I prefer the latter - here's a link I found
> via Google:)
> www.metromidrange.org/iSeries%20GUI%20Debugger.ppt

yes sorry, the C and COBOL programs both are ILE. I have debugged
(strdbg) the called COBOL program of course, it aborts at an
OCCURS-State saying "decimal data error". I think that should have
something to do with the nullflds. The C/C++ Programmer's guide doesn't
really say something about dealing with nullflds, or giving an example
for that - or i just haven't found it yet, maybe.

So do you think the code lines I've posted are correct?

Bye, Chris.

Karl Hanson

unread,
Dec 8, 2006, 11:31:20 AM12/8/06
to

The code you posted seems reasonable from a C standpoint, but I am not
familiar with COBOL linkages (eg LINKAGE SECTION). If the COBOL program
needs to know which (if any) fields in the format are NULL, you are
probably right that the info in the nullflds structure (or equivalent)
somehow needs to be passed to the COBOL program. Would a compiler
output listing of the COBOL program provide any hints? ie would the
COPY DDS-ALL-FORMATS you mentioned be expanded to show all parameters
expected by the COBOL program?

--
Karl Hanson

Elvis

unread,
Dec 8, 2006, 12:51:54 PM12/8/06
to
If your fields allow NULLs, you'll need to set the null map accordingly
in order for _Rwrite etc to work. One byte char value of '0' means
there is valid data and '1' means it's a NULL value.
Here is a simple example:

/* open a file */
_RFILE * p = _Ropen(......);
... set your record's values ....
/* tell DB2 FIELD3 contains a valid value (not NULL) */
p->in_null_map[offsetof(LIB_FILE_FMT_nmap_t,FIELD3)] = '0';
/* write the record */
_Rwrite(p,....);
/* close the file */
_Rclose(p);

HTH

Elvis

Christian Mager

unread,
Dec 14, 2006, 8:58:36 AM12/14/06
to
Hello,

first of all: thanks to everybody helping me solving my problem.

Everything works now. As it turned out I didn't have to use nullmap at
the #pragma mapinc directive, because the called program does checking
for null values itself. If it wouldn't do this, you would have to give
the nullmap as a second parameter to the called program - of course,
the called program must expect this parameter and use it when writing
the data to a file or whatever.

Bye, Chris Mager.

0 new messages