RPG

409. RPGでポインタを学習する(3)

前回ではフィールドからポインタを組込み関数 %ADDR を使って
取得する方法を紹介した。

今度は逆にポインタから変数を定義する具体化(Materiaze)の例を
紹介しよう。
ポインタを基底として変数を定義する例である。

[ RPG: TESTGET ]

ソースはこちらから

0001.00 H DFTNAME(TESTGET) DATEDIT(*YMD/) BNDDIR('QC2LE')                      
0002.00 F********** 環境変数を GETENV *****************************************
0003.00 F*                                                                     
0004.00 F**********************************************************************
0005.00                                                                        
0006.00 D*( GETENV        のプロトタイプ宣言 )                                 
0007.00 D GETENV          PR              *   ExtProc('getenv')                
0008.00 D  ENVVAR                         *   Value                            
0009.00                                                                        
0010.00 D NULL            S              1A   INZ(X'00')                       
0011.00 D STRING          S             48A                                    
0012.00 D STRING_P        S               *   INZ(%ADDR(STRING))               
0013.00 D QRY_STRING_P    S               *                                    
0014.00 D QRY_STRING      S            256A   BASED(QRY_STRING_P)              
0015.00 D FLD40           S             40A                                    
0016.00                                                                        
0017.00 C*( PUTENV QUERY_STRING=FKEY=CF03 + NULL を実行する )                  
0018.00  /FREE                                                                 
0019.00        STRING       = 'QUERY_STRING' + NULL;                           
0020.00        QRY_STRING_P = GETENV(STRING_P);                                
0021.00        FLD40        = %SUBST(QRY_STRING:1:40);                         
0022.00  /END-FREE                                                             
0023.00 C     FLD40         DSPLY                   ANS               1        
0021.00        FLD40        = %SUBST(QRY_STRING:1:40);                     
0022.00  /END-FREE                                                         
0023.00 C     FLD40         DSPLY                   ANS               1    
0024.00 C                   SETON                                        LR
0025.00 C                   RETURN                                         

[コンパイル]

CRTBNDRPG PGM(MYLIB/TESTGET) SRCFILE(MYSRCLIB/QRPGLESRC) DFTACTGRP(*NO)
ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)

[解説]

C言語の関数: getenv は環境変数を読取るAPIでもある。

0020.00        QRY_STRING_P = GETENV(STRING_P); 

によって取得したポインタ値 QRY_STRIN_P に対して
フィールド: QRY_STRING は

0013.00 D QRY_STRING_P    S               *                                    
0014.00 D QRY_STRING      S            256A   BASED(QRY_STRING_P) 

によって多定義されているようにポインタ QRY_STRING_P を基底とする256バイトの
フィールドである。
BASED(QRY_STRING_P) はポインタ QRY_DTRING_P を基底として定義するという意味である。
つまりポインタ QRY_STRIM_P より具体化されてできる変数である。
これによってフィールド QRY_STRING の値を得ることができる。

前回の例では %ADDRによってポインタを求めることが主体であったが
今回はポインタ QRY_STRING_P からフィールド QRY_STRINGを具体化することが
目的である。

このようにポインタはフィールドからフィールドのポインタを取得できるし
逆にポインタからそのポインタから始まるフィールドを定義(具体化)することが
できる。
このようにポインタの使い方を対照的に見比べてみれば
ポインタの使い方がより明確になったのではないかと思う。
このような例や解説はもちろんIBMのマニュアルにもないし
IBM によっても解説されていない。