データストラクチャーの違いについてみて行きましょう。
下記のRPGでは、データストラクチャーDATASを定義しています。
H Y/ 1
H*---------------------------------------------------------------*
H* PROGRAM-ID : ISPEC2R *
H* REMARKS : データストラクチャー *
H* AUTHOR : Y.IDE *
H* DATE-WRITEN : 1999/8/15 *
H* VERSION : 01.00 ORIGINAL *
H*---------------------------------------------------------------*
IDATAS DS
I B 1 40B1
I B 5 60B2
I B 7 100B3
I 11 11 C1
I 12 12 C2
I 13 22 STR
C*
C Z-ADD1 B1
C Z-ADD2 B2
C Z-ADD3 B3
C MOVE 'A' C1
C MOVE 'B' C2
C MOVEL'STRING 'STR
C*
C CALL 'ISPEC2'
C PARM DATAS
C*
C SETON LR
C RETRN
C*
|
このデータストラクチャーは、
4byte+2byte+4byte+1byte+1byte+10byte=22byte
のデータストラクチャーです
そして、このデータストラクチャーDATASをパメーターとして、Cを呼び出しています。
下記のCでは、データストラクチャーONEとTWOを定義しています。それぞれのサブフィールドは同じにしてあります。
ONEとTWOの違いは、TWOの方には_Packedを定義してあり、ONEにはありません。
/*---------------------------------------------------------------*/
/* PROGRAM-ID : ISPEC2 */
/* REMARKS : I仕様書データストラクチャー */
/* AUTHOR : Y.Ide */
/* DATE-WRITEN : 1999/8/15 */
/* VERSION : 01.00 ORIGINAL */
/*---------------------------------------------------------------*/
/* データストラクチャー */
/* RPG C のデータストラクチャーの受渡し */
/* バウンダリーについて理解すること */
/* AS/400の場合は 4 バイトの境界合わせとなる */
#include<stdio.h>
typedef struct Data_Struct_One
{
int b1; /* 4 byte */
short int b2; /* 2 byte */
int b3; /* 4 byte */
char c1; /* 1 byte */
char c2; /* 1 byte */
char str[10]; /* 10 byte */
} Data_Struct_One_t;
typedef _Packed struct Data_Struct_Two
{
int b1; /* 4 byte */
short int b2; /* 2 byte */
int b3; /* 4 byte */
char c1; /* 1 byte */
char c2; /* 1 byte */
char str[10]; /* 10 byte */
} Data_Struct_Two_t;
void main(int argc, char *argv[]){
Data_Struct_One_t *ONE;
Data_Struct_Two_t *TWO;
/*パラメーター取得*/
ONE = (Data_Struct_One_t *)argv[1];
TWO = (Data_Struct_Two_t *)argv[1];
printf("******** Packedしてないデータストラクト********\n");
printf("B1 = %d \n",ONE->b1);
printf("B2 = %d \n",ONE->b2);
printf("B3 = %d \n",ONE->b3);
printf("B3 HEX = %x \n",ONE->b3);
printf("C1 = %c \n",ONE->c1);
printf("C2 = %c \n",ONE->c2);
printf("STR = %s \n",ONE->str);
printf("******** Packedしたデータストラクト********\n");
printf("B1 = %d \n",TWO->b1);
printf("B2 = %d \n",TWO->b2);
printf("B3 = %d \n",TWO->b3);
printf("C1 = %c \n",TWO->c1);
printf("C2 = %c \n",TWO->c2);
printf("STR = %s \n",TWO->str);
}
|
この結果、ONEは正常に表示できず、B3フィールド移行がずれてしまいます。
******** Packed してないデータストラクト ********
B1 = 1
B2 = 2
B3 = 246210
B3 HEX = 3c1c2
C1 = S
C2 = T
STR = RING
******** Packed したデータストラクト ********
B1 = 1
B2 = 2
B3 = 3
C1 = A
C2 = B
STR = STRING
|
[つまりどうゆうこと?]
Cのデータストラクチャーは、_Packedを指定しないと、プログラムがアクセスしやすいバイトごとに、
サブフィールドを割り当てます。AS/400の場合4バイトの境界合わせがおこなわれます。
4バイト+2バイト+4バイト=10バイトの定義が実際は、
4バイト+2バイト+(使用されない2バイト)+4バイト=12バイトとなります。
これに伴なって以降のサブフィールドのデータがずれてしまいます。
上記の場合、データは
00 00 00 01 00 02 00 00 00 03 c1(A) c2(B) ..... と並んでいます。
データストラクチャーONEでは、
00 00 00 01 = B1
00 02 = B2
00 00 境界合わせのために使用されない2バイト
00 03 c1(A) c2(B) = B3(x03c1c2=246210) となっていまいます。
RPGには境界合わせというものがありませんし、コーディングするときに、初めの位置と終わりの位置を定義するので
この様なことはありません。
一般的に、境界合わせした方が、処理自体は高速に処理できますので、RPGなどとデータストラクチャーのやり取りなど
を行うのでなければ、_Packedを使用する必要はありません。
|