For Programmers: Free Programming Magazines  


Home > Archive > Cobol > March 2004 > Problems sending structure to c









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Problems sending structure to c
Cristian Ferrero

2004-03-26, 11:00 pm

I have problems trying to send a structure as parameter from cobol to c
Cobol version is Microfocus Server Express 2.0 revision 011

Example :

---------------- Cobol -----------------------

WORKING-STORAGE SECTION.
01 LINK-VARIABLES.
05 LNK-CHA1 PIC X(16) VALUE ALL X"00".
05 FILLER PIC X(1) VALUE X"00".
05 LNK-CHA2 PIC X(16) VALUE ALL X"00".
05 FILLER PIC X(1) VALUE X"00".
05 LNK-ENT PIC S9(9) COMP-5.

PROCEDURE DIVISION.

INICIO.
MOVE 333333 TO LNK-ENT.
MOVE 'AAAAAAAAAAAAAAAA' TO LNK-CHA1.
MOVE 'BBBBBBBBBBBBBBBB' TO LNK-CHA2.

CALL 'ruti' USING LINK-VARIABLES.

STOP RUN.

---------------- C -----------------------
#include <stdio.h>
typedef struct {
char str1[17];
char str2[17];
long num1;
} estru;
void ruti(estru *est) {
printf("NUM1 %d \n", est->num1);
printf("STR1 %s \n", est->str1);
printf("STR2 %s \n", est->str2);
}

---------------- Output -----------------------
NUM1 370483232
STR1 AAAAAAAAAAAAAAAA
STR2 BBBBBBBBBBBBBBBB

As you can see value from NUM1 is not the real value (333333)
Michael Wojcik

2004-03-26, 11:00 pm


In article <3b9a5e6f.0403220603.1bed1fa9@posting.google.com>, cferrero.edesal@emdersa.com.ar (Cristian Ferrero) writes:
>
> WORKING-STORAGE SECTION.
> 01 LINK-VARIABLES.
> 05 LNK-CHA1 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-CHA2 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-ENT PIC S9(9) COMP-5.
>
> typedef struct {
> char str1[17];
> char str2[17];
> long num1;
> } estru;


C is allowed to insert arbitrary padding bytes between structure
members. There's no guarantee that "num1" is at the same offset
in C as it is in COBOL.

> NUM1 370483232
> As you can see value from NUM1 is not the real value (333333)


Here's the desired value, in hex: 00051615.

Here's the value you saw, in hex: 16152020

Note the sequence of matching bytes: COBOL put 16 and 15 into the two
least significant bytes of the number, and C found those two values
as the two most significant bytes. That's often an indication of an
alignment issue.

Also, the two "garbage" bytes of the value displayed by your C code
are both hex 20, which is the ASCII space character - a value you're
likely to encounter when reading junk out of memory.

In this particular case, with this COBOL implementation calling this
C implementation with these compiler settings, it appears you can
correct the problem by adding two adidtional bytes of filler before
LNK-ENT in your COBOL definition. This will put LNK-ENT on a 4-byte
boundary, which appears to match the offset where C puts num1.

Note, though, that this technique depends entirely on the language
implementations and the particular structures you're trying to pass.
General, portable solutions require using a common representation at
the language boundary which is completely well-defined. That means
either "marshalling" the parameters into a well-defined binary stream
format, and "unmarshalling" them on the other side, or using a more
verbose streaming representation such as XML.

Of course, many programs take the easy route and simply massage
native language structures - what you have here - until everything
works, and don't worry that what they have is nonportable. For many
problem domains that's fine; not every program needs to be portable.

--
Michael Wojcik michael.wojcik@microfocus.com

Advertising Copy in a Second Language Dept.:
The precious ovum itself is proof of the oath sworn to those who set
eyes upon Mokona: Your wishes will be granted if you are able to invest
it with eternal radiance... -- Noriyuki Zinguzi
Cristian Ferrero

2004-03-26, 11:00 pm

cferrero.edesal@emdersa.com.ar (Cristian Ferrero) wrote in message news:<3b9a5e6f.0403220603.1bed1fa9@posting.google.com>...
> I have problems trying to send a structure as parameter from cobol to c
> Cobol version is Microfocus Server Express 2.0 revision 011
>
> Example :
>
> ---------------- Cobol -----------------------
>
> WORKING-STORAGE SECTION.
> 01 LINK-VARIABLES.
> 05 LNK-CHA1 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-CHA2 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-ENT PIC S9(9) COMP-5.
>
> PROCEDURE DIVISION.
>
> INICIO.
> MOVE 333333 TO LNK-ENT.
> MOVE 'AAAAAAAAAAAAAAAA' TO LNK-CHA1.
> MOVE 'BBBBBBBBBBBBBBBB' TO LNK-CHA2.
>
> CALL 'ruti' USING LINK-VARIABLES.
>
> STOP RUN.
>
> ---------------- C -----------------------
> #include <stdio.h>
> typedef struct {
> char str1[17];
> char str2[17];
> long num1;
> } estru;
> void ruti(estru *est) {
> printf("NUM1 %d \n", est->num1);
> printf("STR1 %s \n", est->str1);
> printf("STR2 %s \n", est->str2);
> }
>
> ---------------- Output -----------------------
> NUM1 370483232
> STR1 AAAAAAAAAAAAAAAA
> STR2 BBBBBBBBBBBBBBBB
>
> As you can see value from NUM1 is not the real value (333333)




Michael ,we are in serious troubles because we are in the middle of
an implementation and this is a serious problem.
The example i gave to you works fine in OBJECT COBOL 4.1 , and we
have all our programs like that, now we are trying to move to
Microfocus Server Express 2.0 , and the example works only if we move
the numeric value before the string like this :
WORKING-STORAGE SECTION.
01 LINK-VARIABLES.
05 LNK-ENT PIC S9(9) COMP-5.
05 LNK-CHA1 PIC X(16) VALUE ALL
X"00".
05 FILLER PIC X(1) VALUE X"00".
05 LNK-CHA2 PIC X(16) VALUE ALL
X"00".
05 FILLER PIC X(1) VALUE X"00".

PROCEDURE DIVISION.

INICIO.
MOVE 333333 TO LNK-ENT.
MOVE 'AAAAAAAAAAAAAAAA' TO LNK-CHA1.
MOVE 'BBBBBBBBBBBBBBBB' TO LNK-CHA2.

CALL 'ruti' USING LINK-VARIABLES.

STOP RUN.

---------------- C -----------------------
#include <stdio.h>
typedef struct {
long num1;
char str1[17];
char str2[17];
} estru;
void ruti(estru *est) {
printf("NUM1 %d \n", est->num1);
printf("STR1 %s \n", est->str1);
printf("STR2 %s \n", est->str2);
}

We try to use your example but the result of the value was 0. Please
tell me something...

THANKS !!! AND SORRY ABOUT MY ENGLISH
William M. Klein

2004-03-26, 11:00 pm

I notice that you have 34 bytes before your COMP-5 field. You might try adding
a 2-byte filler just before the COMP-5 field - so that (in COBOL) it is on a
fullword boundary. Alternatively, check to see if MF allows SYNC on COMP-5
fields (I can't remember if this is or isn't allowed by them).

I won't SWEAR that this will solve the problem, but it MIGHT.

--
Bill Klein
wmklein <at> ix.netcom.com
"Cristian Ferrero" <cferrero.edesal@emdersa.com.ar> wrote in message
news:3b9a5e6f.0403221029.72f525a7@posting.google.com...
> cferrero.edesal@emdersa.com.ar (Cristian Ferrero) wrote in message

news:<3b9a5e6f.0403220603.1bed1fa9@posting.google.com>...
>
>
>
> Michael ,we are in serious troubles because we are in the middle of
> an implementation and this is a serious problem.
> The example i gave to you works fine in OBJECT COBOL 4.1 , and we
> have all our programs like that, now we are trying to move to
> Microfocus Server Express 2.0 , and the example works only if we move
> the numeric value before the string like this :
> WORKING-STORAGE SECTION.
> 01 LINK-VARIABLES.
> 05 LNK-ENT PIC S9(9) COMP-5.
> 05 LNK-CHA1 PIC X(16) VALUE ALL
> X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-CHA2 PIC X(16) VALUE ALL
> X"00".
> 05 FILLER PIC X(1) VALUE X"00".
>
> PROCEDURE DIVISION.
>
> INICIO.
> MOVE 333333 TO LNK-ENT.
> MOVE 'AAAAAAAAAAAAAAAA' TO LNK-CHA1.
> MOVE 'BBBBBBBBBBBBBBBB' TO LNK-CHA2.
>
> CALL 'ruti' USING LINK-VARIABLES.
>
> STOP RUN.
>
> ---------------- C -----------------------
> #include <stdio.h>
> typedef struct {
> long num1;
> char str1[17];
> char str2[17];
> } estru;
> void ruti(estru *est) {
> printf("NUM1 %d \n", est->num1);
> printf("STR1 %s \n", est->str1);
> printf("STR2 %s \n", est->str2);
> }
>
> We try to use your example but the result of the value was 0. Please
> tell me something...
>
> THANKS !!! AND SORRY ABOUT MY ENGLISH



Stephen Gennard

2004-03-26, 11:00 pm

This is a classic alignment issue, you can quickly verify this by checking
what COBOL thinks the group item should be and what C thinks the struct size
should be. Eg. insert:

display length of LINK-VARIABLES.

and into the 'C'.

printf("size = %d\n",sizeof(estru));

You will 'C' thinks it is 40 and COBOL thinks it is 38. The 'C' compiler
has added two extra spaces between the two char arrays, so that the pointers
in the structure are nicely aligned.

To solve the issue you will need to compile 'C' with the right alignment, on
AIX, add the directive "-qalign=packed" to your 'C' directives:

For example:

# cob -via a.cbl
* Micro Focus Server Express V2.2 revision 000 Compiler
* Copyright (C) 1984-2002 Micro Focus International Ltd. URN RXCAI/AA0/00000
* Accepted - verbose
* Accepted - nolist
* Compiling a.cbl
* Total Messages: 0
* Data: 504 Code: 116
# xlc -c -g -qalign=packed ruti.c
# cob -vzg ruti.o
# cobrun a
NUM1 333333
STR1 AAAAAAAAAAAAAAAA
STR2 BBBBBBBBBBBBBBBB

Other platforms have simular directives.
--
Stephen


"Cristian Ferrero" <cferrero.edesal@emdersa.com.ar> wrote in message
news:3b9a5e6f.0403220603.1bed1fa9@posting.google.com...
> I have problems trying to send a structure as parameter from cobol to c
> Cobol version is Microfocus Server Express 2.0 revision 011
>
> Example :
>
> ---------------- Cobol -----------------------
>
> WORKING-STORAGE SECTION.
> 01 LINK-VARIABLES.
> 05 LNK-CHA1 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-CHA2 PIC X(16) VALUE ALL X"00".
> 05 FILLER PIC X(1) VALUE X"00".
> 05 LNK-ENT PIC S9(9) COMP-5.
>
> PROCEDURE DIVISION.
>
> INICIO.
> MOVE 333333 TO LNK-ENT.
> MOVE 'AAAAAAAAAAAAAAAA' TO LNK-CHA1.
> MOVE 'BBBBBBBBBBBBBBBB' TO LNK-CHA2.
>
> CALL 'ruti' USING LINK-VARIABLES.
>
> STOP RUN.
>
> ---------------- C -----------------------
> #include <stdio.h>
> typedef struct {
> char str1[17];
> char str2[17];
> long num1;
> } estru;
> void ruti(estru *est) {
> printf("NUM1 %d \n", est->num1);
> printf("STR1 %s \n", est->str1);
> printf("STR2 %s \n", est->str2);
> }
>
> ---------------- Output -----------------------
> NUM1 370483232
> STR1 AAAAAAAAAAAAAAAA
> STR2 BBBBBBBBBBBBBBBB
>
> As you can see value from NUM1 is not the real value (333333)



Richard

2004-03-26, 11:00 pm

cferrero.edesal@emdersa.com.ar (Cristian Ferrero) wrote

[color=darkred]
> Michael ,we are in serious troubles because we are in the middle of
> an implementation and this is a serious problem.
> The example i gave to you works fine in OBJECT COBOL 4.1 , and we
> have all our programs like that, now we are trying to move to
> Microfocus Server Express 2.0 , and the example works only if we move
> the numeric value before the string like this :


Have you also changed the C compiler ? Have you changed the compiler
settings ?

It seems to me that you had the C compiler byte aligned on structures
so that num1 started in byte 34, but other C compiler settings may
have caused this long integer to now start on a 4byte or 8 byte
boundary, thus it starts on byte 36, or perhaps byte 40 if str2 is
starting on byte 20.

Is the value in str2 3 bytes shorter than it should be ? If so then
that would definately indicate that the C compiler was padding to 4
byte boundaries.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com