V5R4 CL で API とポインタを使う - CHKACTJOB の書き直し -

V5R4 以降では、CL でも API を扱う時に「System API プログラミングの基礎 (1)」で紹介したユーザースペースをポインタでアクセスする手法が使えます。

System API の使用例 - CL から V5R4 CL への書き直し -」で書き直した CL をさらに、ポインタを使用する形に書き直してみました。

こちらがプログラムの全文です。

             PGM        PARM(&PARM1 &STS)          
                             
     /* 引数の定義*/                                                                 
             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         
             DCL        VAR(&JOBPARM) TYPE(*CHAR) LEN(26)                       
             DCL        VAR(&JOB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 1)                                      
             DCL        VAR(&USR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 11)                                     
             DCL        VAR(&NBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) +            
                          DEFVAR(&PARM1 21)                                     
             DCL        VAR(&STS) TYPE(*CHAR) LEN(10)                           
     /* ユーザースペース*/                                                              
             DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(20) +                      
                          VALUE('CHKACTJOB QTEMP     ')                         
             DCL        VAR(&USOBJ) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 1)                             
             DCL        VAR(&USLIB) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 11)                            
     /* ヘッダ項目 */                                                                
             DCL        VAR(&HDRP) TYPE(*PTR)                     
             DCL        VAR(&HDR) TYPE(*CHAR) STG(*BASED) LEN(192) +            
                          BASPTR(&HDRP)                                         
             DCL        VAR(&ENTRY) TYPE(*UINT) STG(*DEFINED) LEN(4) +          
                          DEFVAR(&HDR 133)                                      
             DCL        VAR(&OFFSET) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 125)                               
             DCL        VAR(&ENTLEN) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 137)                               
     /* リスト項目 */                                                                
             DCL        VAR(&LSTJOBEP) TYPE(*PTR)                 
             DCL        VAR(&LSTJOBE) TYPE(*CHAR) STG(*BASED) +                 
                          LEN(52) BASPTR(&LSTJOBEP)                             
             DCL        VAR(&JOBNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 1)                            
             DCL        VAR(&USRNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 11)                           
             DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(6) DEFVAR(&LSTJOBE 21)                            
             DCL        VAR(&JOBSTS) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&LSTJOBE 43)                           
     /* カウンタ */                                                                 
             DCL        VAR(&I) TYPE(*INT) LEN(2)                               

     /* 引数のチェック*/                                                               
             IF         COND(&JOB = '          ') THEN(CHGVAR +                 
                          VAR(&JOB) VALUE('*ALL     '))                         
             IF         COND(&USR = '          ') THEN(CHGVAR +                 
                          VAR(&USR) VALUE('*ALL     '))                         
             IF         COND(&NBR = '      ') THEN(CHGVAR VAR(&NBR) +           
                          VALUE('*ALL  '))                                      
             IF         COND(&STS = '          ') THEN(CHGVAR +                 
                          VAR(&STS) VALUE('*ALL     '))                         
     /* 初期化*/                                                                   
             CHKOBJ     OBJ(&USLIB/&USOBJ) OBJTYPE(*USRSPC)                     
             MONMSG     MSGID(CPF9801) EXEC(+                                   
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE'))                               
             CLRPFM     FILE(QCHKACTJ)                                          
     /* ジョブ情報の取得*/                                                              
             CHGVAR     VAR(%SST(&JOBPARM 1 10)) VALUE(&JOB)                    
             CHGVAR     VAR(%SST(&JOBPARM 11 10)) VALUE(&USR)                   
             CHGVAR     VAR(%SST(&JOBPARM 21 6)) VALUE(&NBR)                    
             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100' +                  
                          &JOBPARM &STS)                                        
     /* ジョブ情報項目の取得*/                                                            
             CALL       PGM(QUSPTRUS) PARM(&USRSPC &HDRP)                       
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CHGVAR     VAR(&LSTJOBEP) VALUE(&HDRP)                             
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &OFFSET)                   
     /* ループ*/                                                                   
             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &ENTLEN)                   
             ENDDO                                                              
 NOJOB:      ENDPGM

情報取得のための API 呼び出しを不要にする

ジョブ情報の各項目を API の返り値から切り出してくる処理ですが、「System API の使用例 - CL から V5R4 CL への書き直し -」の時には

     /* ジョブ情報項目の取得*/                                                            
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085' +                
                          X'00000004' &ENTRY)                                   
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000089' +                
                          X'00000004' &ENTLEN)                                  
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'0000007D' +                
                          X'00000004' &OFFSET)                                  
             CHGVAR     VAR(&STR) VALUE(&OFFSET + 1)                            
     /* ループ*/                                                                   
             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALL       PGM(QUSRTVUS) PARM(&USRSPC &STR &ENTLEN +               
                          &LSTJOBE)                                             
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(&STR) VALUE(&STR + &ENTLEN)                         
             ENDDO                                                              

だったのが、

     /* ジョブ情報項目の取得*/                                                            
             CALL       PGM(QUSPTRUS) PARM(&USRSPC &HDRP)                       
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CHGVAR     VAR(&LSTJOBEP) VALUE(&HDRP)                             
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &OFFSET)                   
     /* ループ*/                                                                   
             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &ENTLEN)                   
             ENDDO         

というように書き直せます。
API を呼び出す CALL の回数が 5回から 1回に激減しているのがわかりますね。

定義済み変数 = データ・ストラクチャ

System API の使用例 - CL から RPG への書き直し -」の RPG への書き直しでは基底ポインタを指定したデータ・ストラクチャを利用しましたが、V5R4 以降の CL であれば「System API の使用例 - CL から V5R4 CL への書き直し -」でも使用した定義済み変数で RPG と同様のことができます。

     /* ヘッダ項目 */                                                                
             DCL        VAR(&HDRP) TYPE(*PTR)                     
             DCL        VAR(&HDR) TYPE(*CHAR) STG(*BASED) LEN(192) +            
                          BASPTR(&HDRP)                                         
             DCL        VAR(&ENTRY) TYPE(*UINT) STG(*DEFINED) LEN(4) +          
                          DEFVAR(&HDR 133)                                      
             DCL        VAR(&OFFSET) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 125)                               
             DCL        VAR(&ENTLEN) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 137)                               
     /* リスト項目 */                                                                
             DCL        VAR(&LSTJOBEP) TYPE(*PTR)                 
             DCL        VAR(&LSTJOBE) TYPE(*CHAR) STG(*BASED) +                 
                          LEN(52) BASPTR(&LSTJOBEP)                             
             DCL        VAR(&JOBNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 1)                            
             DCL        VAR(&USRNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 11)                           
             DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(6) DEFVAR(&LSTJOBE 21)                            
             DCL        VAR(&JOBSTS) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&LSTJOBE 43)    

CL にコンパイラは C などと同様に最初から順に解釈していきます。
BASPTR (基底ポインタ) に指定するポインタ変数は先に定義しておかないとコンパイルエラーになります。

ポインタ変数の内容

デバッガで見てみましょう。ポインタ変数の内容は QUSPTRUS という API の結果によってセットされていることが確認できます。

一番最初の実行なので以下のような値が入ってきていますが、ジョブの中での各実行毎に内容は変わります。

QUSPTRUS API の呼び出し後、指定したポインタ変数にはユーザースペースの開始アドレスがセットされていることが確認できます。

上記プログラムを実行しようとするとコンパイルはうまくいくのですが、実行時にポインタ変数の初期化がうまくできずに機械チェックになってしまうシステムがありました。
PTF なのか、それともなんらかの設定なのか ...... 未だ解明できていないのですが、↓のようにダミーの変数を作ってそのアドレスを先に代入させてしまうことによって実行可能になりました。

     /* ヘッダ項目 */                                                                
             DCL        VAR(&DMY) TYPE(*CHAR) LEN(1)                            
             DCL        VAR(&HDRP) TYPE(*PTR) ADDRESS(&DMY)                     
             DCL        VAR(&HDR) TYPE(*CHAR) STG(*BASED) LEN(192) +            
                          BASPTR(&HDRP)

あまり納得はいっていないのですが、「V5R4 での CL の拡張」で紹介したポインタのコーディング例でも DCL 文で↑と同様にアドレスを取得しているので、こういうものなのかもしれない (?!) ですねぇ ...... 一応こちらのバージョンの全文も載せておきます。

             PGM        PARM(&PARM1 &STS)          
                             
     /* 引数の定義*/                                                                 
             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         
             DCL        VAR(&JOBPARM) TYPE(*CHAR) LEN(26)                       
             DCL        VAR(&JOB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 1)                                      
             DCL        VAR(&USR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 11)                                     
             DCL        VAR(&NBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) +            
                          DEFVAR(&PARM1 21)                                     
             DCL        VAR(&STS) TYPE(*CHAR) LEN(10)                           
     /* ユーザースペース*/                                                              
             DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(20) +                      
                          VALUE('CHKACTJOB QTEMP     ')                         
             DCL        VAR(&USOBJ) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 1)                             
             DCL        VAR(&USLIB) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 11)                            
     /* ヘッダ項目 */                                                                
             DCL        VAR(&DMY) TYPE(*CHAR) LEN(1)                            
             DCL        VAR(&HDRP) TYPE(*PTR) ADDRESS(&DMY)                     
             DCL        VAR(&HDR) TYPE(*CHAR) STG(*BASED) LEN(192) +            
                          BASPTR(&HDRP)                                         
             DCL        VAR(&ENTRY) TYPE(*UINT) STG(*DEFINED) LEN(4) +          
                          DEFVAR(&HDR 133)                                      
             DCL        VAR(&OFFSET) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 125)                               
             DCL        VAR(&ENTLEN) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&HDR 137)                               
     /* リスト項目 */                                                                
             DCL        VAR(&LSTJOBEP) TYPE(*PTR) ADDRESS(&DMY)                 
             DCL        VAR(&LSTJOBE) TYPE(*CHAR) STG(*BASED) +                 
                          LEN(52) BASPTR(&LSTJOBEP)                             
             DCL        VAR(&JOBNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 1)                            
             DCL        VAR(&USRNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 11)                           
             DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(6) DEFVAR(&LSTJOBE 21)                            
             DCL        VAR(&JOBSTS) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&LSTJOBE 43)                           
     /* カウンタ */                                                                 
             DCL        VAR(&I) TYPE(*INT) LEN(2)                               

     /* 引数のチェック*/                                                               
             IF         COND(&JOB = '          ') THEN(CHGVAR +                 
                          VAR(&JOB) VALUE('*ALL     '))                         
             IF         COND(&USR = '          ') THEN(CHGVAR +                 
                          VAR(&USR) VALUE('*ALL     '))                         
             IF         COND(&NBR = '      ') THEN(CHGVAR VAR(&NBR) +           
                          VALUE('*ALL  '))                                      
             IF         COND(&STS = '          ') THEN(CHGVAR +                 
                          VAR(&STS) VALUE('*ALL     '))                         
     /* 初期化*/                                                                   
             CHKOBJ     OBJ(&USLIB/&USOBJ) OBJTYPE(*USRSPC)                     
             MONMSG     MSGID(CPF9801) EXEC(+                                   
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE'))                               
             CLRPFM     FILE(QCHKACTJ)                                          
     /* ジョブ情報の取得*/                                                              
             CHGVAR     VAR(%SST(&JOBPARM 1 10)) VALUE(&JOB)                    
             CHGVAR     VAR(%SST(&JOBPARM 11 10)) VALUE(&USR)                   
             CHGVAR     VAR(%SST(&JOBPARM 21 6)) VALUE(&NBR)                    
             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100' +                  
                          &JOBPARM &STS)                                        
     /* ジョブ情報項目の取得*/                                                            
             CALL       PGM(QUSPTRUS) PARM(&USRSPC &HDRP)                       
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CHGVAR     VAR(&LSTJOBEP) VALUE(&HDRP)                             
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &OFFSET)                   
     /* ループ*/                                                                   
             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(%OFFSET(&LSTJOBEP)) +                               
                          VALUE(%OFFSET(&LSTJOBEP) + &ENTLEN)                   
             ENDDO                                                              
 NOJOB:      ENDPGM

[Top Pageに戻る]

Ads by TOK2