ILEでのプログラム作成
目 次 へ


ILE(統合言語環境)で構築したシステムは、ダイナミックリンクのオーバーヘッドがなくなり、
高い処理効率が得られるようになります。特にチューンナップしていないプログラムとの比較では
ざっと100倍の効率アップが得られるようです。

ILEでシステム構築をする場合、同一言語でのバインドだけでなく、RPGとCOBOLや
COBOLとC言語など異なる言語をバインドしてのプログラム組み立てとなることもあります。

ここでは、実際に異なる言語のモジュールを組み合わせてプログラム構築を試してみました。





別々のコンパイルタイミングでのモジュールの作成



チーム・プレーでプログラム開発を行う場合、プログラムを適当に分割して、別々のタイミングで開発し、

ソース    モジュール    プログラム

の手順の分割建造法をとることになります。
その場合の手順、注意点について紹介します。

分割建造法の手順

手順はモジュールとよばれる中間製品を作成し、これをバインドして一つの実行可能プログラムにします。
その手順は次のとおりです。

手順1.モジュールの作成

言語の種類を問わず、コーディングをおえたなら、モジュール(*MODULE)を作成します。
モジュールの作成は独立して(それぞれ別々のタイミングで)行われます。
モジュール作成のCLは次のとおりです。例はILE−RPGです。

  CRTRPGMOD MODULE(WRKLIB/TEST4R) SRCFILE(*LIBL/QRPGLESRC)
  CRTRPGMOD MODULE(WRKLIB/TEST4R1) SRCFILE(*LIBL/QRPGLESRC)


手順2.実行プログラムの作成

それぞれのモジュールが完成したなら、それらをバインド(汎用機のリンクエディット)して
ひとつのプログラムをくみ上げます。以下はその例です。これは言語の種類によりません。

  CRTPGM PGM(WRKLIB/TEST4R) MODULE(*LIBL/TEST4R *LIBL/TEST4R1) +
  DETAIL(*BASIC)


DETAILパラメータはバインドの結果のレポートの詳しさです。
ここでは*BASICを指定しています。

手順3.実行


通常のプログラムと同様に直接CALLあるいは,サブミット、あるいはメニューから呼び出しで
実行します。

CALL PGM(WRKLIB/TEST4R)


ILE−RPGのページでもふれましたが、RPGの場合呼び出し側にプロトタイプの定義が必要です。
以下にサンプルを示します。

メイン・プロシージャー(TEST4R)
H DATEDIT(*YMD-)                                               
D*------------------------------------                               
D* プロトタイプの指定                                           
D TEST4R1         PR                                           
D                                4A                            
D                                9B 0                          
D                                9P 0                          
D*------------------------------------                         
D  AA             S              4A                            
D  BB             S              9B 0                          
D  CC             S              9P 0                          
C*------------------------------------                         
C                   MOVEL     '1234'        AA                 
C                   Z-ADD     9876          BB                 
C                   Z-ADD     000           CC                 
C*                                                             
C                   CALLP     TEST4R1 (AA: BB: CC)             
C     AA            DSPLY                                      
C     BB            DSPLY                                      
C     CC            DSPLY                                      
C                   SETON   
C                   RETURN  

注意点:バインド予定のプロシージャーの呼び出しは、CALLP命令を使用します。

サブ・プロシージャー(TEST4R1)
H  NOMAIN                                                            
DTEST4R1          PR                                                 
D  AA                            4A                                  
D  BB                           10I 0                                
D  CC                            9P 0                                
PTEST4R1          B                   EXPORT                         
D*------------------------------------                               
DTEST4R1          PI                                                 
D  AA                            4A                                  
D  BB                           10I 0                                
D  CC                            9P 0                                
C*------------------------------------                               
C*                                                                   
C                   MOVEL     'ABCD'        AA                       
C     BB            DIV       2             BB                       
C     BB            MULT      3             CC                       
C*                                                                   
C                   RETURN                                           
C                   SETON                                        LR  
P                 E                                                  

サブ・プロシージャーではEXPORTパラメータで「外部」、「入り口」の属性を与えます。(下線部)

EXPORTされていないと、外部からTEST4R1の入口点が見えません。
CRTPGMでは一見正常にバインドが完了しますが、実行するとCALLがかかったとき、
エラーになってしまいます。(本来ならCRTPGMでエラーにすべきと思うのですが)

また、モジュール名と入口名が別のとき、たとえばメインがSUB1をCALLPしていて、
サブのモジュール名がSUB1,入口名がSUB1Aのときは、CRTPGMは正常に完了するが、
できあがったプログラムは実行しても正常にRUNしません。


異なった言語からのモジュールのバインド

RPG,COBOL,CL,Cなど異なった言語でできたモジュールの組合せを試してみました。
ここではプロシージャー名は次のように命名しています。

メイン サブ
RPG−IV TEST4R TEST4R1
COBOL TESTCB TESTCB1
CL ( TESTCL) TESTCL1
TESTC TESTC1

1. RPGメインからRPG,COB,CL,Cの呼出し

RPGをメインとして各種の言語のプロシージャーを呼び出しを行っています。

RPGメイン(TEST4R)のソース

H DATEDIT(*YMD-)                                                     
D*----------------------------------------------------    
D* プロトタイプの指定                  
D TEST4R1         PR                   
D                               10A    
D                                9B 0  
D                                9P 0  
D                                8F    
D TESTCB1         PR                   
D                               10A    
D                                9B 0  
D                                9P 0  
D                                8F    
D TESTCL1         PR                   
D                               10A    
D                                9B 0  
D                                9P 0  
D                                8F    
D TESTC1          PR                   
D                               10A    
D                                9B 0                     
D                                9P 0                     
D                                8F       
D*----------------------------------------------------             
C                   MOVEL     *BLANK        AA            
C                   Z-ADD     12345         BB            
C                   Z-ADD     000           CC            
C                   Z-ADD     000           DD            
C* --> RPG                                                
C                   CALLP     TEST4R1 (AA: BB: CC: DD)    
C                   EXSR      SBDSP                       
C* --> COB                                                
C                   CALLP     TESTCB1 (AA: BB: CC: DD)    
C                   EXSR      SBDSP                       
C* --> CL1                                                
C                   CALLP     TESTCB1 (AA: BB: CC: DD)              
C                   EXSR      SBDSP                                 
C* --> C1                                                           
C                   CALLP     TESTC1  (AA: BB: CC: DD)              
C                   EXSR      SBDSP                                 
C*                                                                  
C                   SETON                                        LR 
C                   RETURN                                          
C*----------------------------------------------                    
C*    SBDSP         DSPLAY                                          
C*----------------------------------------------                    
C     SBDSP         BEGSR                                           
C*                                                                  
C     AA            DSPLY                                           
C     BB            DSPLY                                           
C     CC            DSPLY                                           
C     DD            DSPLY                                           
C*                                                                  
C                   ENDSR                                           
                              

注意:呼び出しするプロシージャーのプロトタイプをすべて宣言しています。
    呼び出しはCALLPです。
    受け渡しするパラメータは10バイトの文字列、4バイトのバイナリー、9桁の
    パック10進数、倍精度の浮動小数点数です。

RPGサブのソース

H  NOMAIN                                                     
DTEST4R1          PR                                          
D  AA                           10A                           
D  BB                           10I 0                         
D  CC                            9P 0                         
D  DD                            8F                           
PTEST4R1          B                   EXPORT                  
D*------------------------------------                        
DTEST4R1          PI                                          
D  AA                           10A                           
D  BB                           10I 0                         
D  CC                            9P 0                         
D  DD                            8F                           
C*------------------------------------                        
C*                                                            
C                   MOVEL     'TEST4R1...'  AA                
C     BB            DIV       3             BB                
C     BB            MULT      4             CC                
C     CC            DIV       5             DD                
C*                                                            
C                   RETURN                                           
C                   SETON                                        LR  
P                 E                                                    

もらった数値データの1/3と4/3と4/15を計算して返しています。

COBOLサブ・プログラム・ソース
       PROCESS  APOST                                                 
       IDENTIFICATION      DIVISION.                                  
       PROGRAM-ID.         TESTCB1.                                   
       AUTHOR.             KAJIROU.                                   
       ENVIRONMENT         DIVISION.                                  
       CONFIGURATION       SECTION.                                   
         SOURCE-COMPUTER.  HAL-5000.                                  
         OBJECT-COMPUTER.  HAL-5000.                                  
       INPUT-OUTPUT        SECTION.                                   
         FILE-CONTROL.                                                
      *----------------------------------------------------------     
       DATA                        DIVISION.                          
       WORKING-STORAGE  SECTION.                                      
       LINKAGE          SECTION.                                      
       01      AAA            PIC  X(10).                             
       01      BBB            PIC  S9(09)  COMP-4.                    
       01      CCC            PIC  S9(09)  COMP-3.                    
       01      DDD                         COMP-2.  
      *---------------------------------------------------------------
       PROCEDURE         DIVISION   USING   AAA  BBB  CCC  DDD.   
       01.                                                        
           MOVE    'TESTCB1...'   TO   AAA.                       
           COMPUTE  BBB        =    BBB  / 2.                     
           COMPUTE  CCC        =    BBB  * 3.                     
           COMPUTE  DDD        =    CCC  / 4.                     
           GOBACK.                                                 

もらった数値データの1/2と3/2と3/8を計算して返しています。

CLサブプログラム(TESTCL1)のソース
PGM   PARM(&AA  &BB  &CC  &DD)                           
                                                         
      DCL  &AA  *CHAR  10      /*  文字列             */ 
      DCL  &BB  *CHAR  4       /*  2進数用           */ 
      DCL  &CC  *DEC   9       /*  パック10進数     */ 
      DCL  &DD  *CHAR  8       /*  浮動小数点用       */ 
      DCL  &WK  *CHAR  2       /*  2進数用ワーク     */ 
                                                         
      CHGVAR    &AA  VALUE('TESTCL1...')                 
      CHGVAR    &WK  VALUE(%SST(&BB 3 2))                
      CHGVAR    &CC  VALUE(%BIN(&BB) * 5)                
                                                          

CLプログラムではバイナリーはサポートしていません。そのため、このプログラムでは
&BBで取得した4バイトバイナリーの下2バイト分をバイナリーとして解釈して計算し、
2倍にして&CCで返しています。また、浮動小数点数もサポートしていないので、
同じバイト数のパラメータだけ用意するだけで、何もしていません。
呼出しプログラムは9桁のパック10進数で受け取ります。


Cプログラム(TESTC1)のソース
   #include <unistd.h>                                             
   #include <decimal.h>   /*  パック10進数を使うとき必要  */      
   void TESTC1(char *AA, int  *BB, decimal(9,0) *CC, double *DD)    
   {                                                                
       memcpy(AA, "TESTC1....", 10);                                
       *BB = *BB / 5 ;                                              
       *CC = (decimal(9,0)) (*BB *6);                               
       *DD = (float) *CC / 7;                                       
       return;                                                      
   }                                                                

このプログラムではもらった数値データの1/5と6/5と6/35を計算してかえしています。


プログラム作成手順は次のようになります。

手順.1モジュールの作成
CRTRPGMOD MODULE(WRKLIB/TEST4R) SRCFILE(*LIBL/QRPGLESRC)
CRTRPGMOD MODULE(WRKLIB/TESTC4R1) SRCFILE(*LIBL/QRPGLESRC)
CRTCBLMOD MODULE(WRKLIB/TESTCCB1) SRCFILE(*LIBL/QCBLLESRC)
CRTCBLMOD MODULE(WRKLIB/TESTCCL1) SRCFILE(*LIBL/QCLLESRC)
CRTCBLMOD MODULE(WRKLIB/TESTC1) SRCFILE(*LIBL/QCSRC)


手順.2バインド・プログラムの作成

CRTPGM PGM(WRKLIB/TEST4R) MODULE(TEST4R TEST4R1 TESTCB1 TESTCL1 TESTC1) -
      DETAIL(*BASIC)



2.COBがメインの場合 COB,RPG,CL,C

COBOメイン・プログラム
       PROCESS  APOST                                                 
       IDENTIFICATION DIVISION.                                       
       PROGRAM-ID.   TESTCB.                                          
       AUTHOR.                     KAJIROU.                           
       ENVIRONMENT                 DIVISION.                          
       CONFIGURATION               SECTION.                           
         SOURCE-COMPUTER.          HAL-5000.                          
         OBJECT-COMPUTER.          HAL-5000.                          
       INPUT-OUTPUT                SECTION.                           
         FILE-CONTROL.                                                
      *----------------------------------------------------------     
       DATA                        DIVISION.                          
      *----------------------------------------------------------     
       WORKING-STORAGE  SECTION.                                      
       01      AA             PIC  X(10).                             
       01      BB             PIC  S9(09)  COMP-4.                    
       01      CC             PIC  S9(09)  COMP-3.                    
       01      DD             COMP-2. 
      *---------------------------------------------------------------
       PROCEDURE         DIVISION.                                    
       01.                                                            
           MOVE  SPACE   TO     AA.                             
           MOVE  12345   TO     BB.                             
           MOVE  0       TO     CC.                             
           MOVE  0       TO     DD.                            
       02.                                                     
           CALL  PROCEDURE  'TESTCB1' USING  AA    BB  CC  DD. 
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD.   
                                                               
           CALL  PROCEDURE  'TEST4R1' USING  AA    BB  CC  DD. 
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD.   
                                                               
           CALL  PROCEDURE  'TESTCL1' USING  AA    BB  CC  DD. 
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD.   
                                                               
           CALL  PROCEDURE  'TESTC1'  USING  AA    BB  CC  DD. 
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD.   
       03.                                                      
           STOP  RUN.                                           

注意:CALL命令はLINKAGE TYPE IS PROCEDUREです。
    これをつけないと、一見バインドが正常に終わったように見えても実行時にエラーになります。
    LINKAGE TYPE ISは省略可能なので略しています。

各サブ・プログラム

既出、省略します。

プログラム作成手順

手順1.モジュール作成
     省略

手順2.プログラム作成

CRTPGM PGM(WRKLIB/TESTCB) MODULE(TESTCB TEST4R1 TESTCB1 TESTCL1 TESTC1) -
       DETAIL(*BASIC)



3.C言語によるメイン・プログラム

   
   #include  <stdio.h>                                               
   #include  <stdlib.h>                                              
   #include  <unistd.h>     /*  for  memcpy                     */   
   #include  <decimal.h>    /*  パック10進数を使うとき必要    */   
   void TEST4R1(char *AA, int *BB, decimal(9,0) *CC, double *DD);    
   void TESTCB1(char *AA, int *BB, decimal(9,0) *CC, double *DD);    
   void TESTCL1(char *AA, int *BB, decimal(9,0) *CC, double *DD);    
   void TESTC1(char *AA,  int *BB, decimal(9,0) *CC, double *DD);    
                                                                     
   void main(int argc, char *argv[])                                 
   {                                                                 
       char          AA[10];        /*  文字列                  */   
       int           BB ;           /*  INTEGER*4               */   
       decimal(9,0)  CC ;           /*   パック10進数         */   
       double        DD ;           /*  REAL*8                  */   
       int           WK ;           /*  INTEGER*4  WORK         */   
                                                                     
       memcpy(AA, "          ", 10);                                 
       BB = 12345;                                                   
       CC = 0 ;                                                      
       DD = 0 ;                                                       
       TEST4R1(AA, &BB, &CC, &DD);     /* CALL TEST4R1(AA,BB,CC,DD) */
       WK = (int) CC;                                                 
       printf(" AA= %10s BB= %d CC=%d DD=%f ??/n", AA,BB,WK,DD);      
       TESTCB1(AA, &BB, &CC, &DD);     /* CALL TESTCB1(AA,BB,CC,DD) */
       WK = (int) CC;                                                 
       printf(" AA= %s BB= %d CC=%d DD=%f ??/n", AA,BB,WK,DD);        
       TESTCL1(AA, &BB, &CC, &DD);     /* CALL TESTCL1(AA,BB,CC,DD) */
       WK = (int) CC;                                                 
       printf(" AA= %s BB= %d CC=%d DD=%f ??/n", AA,BB,WK,DD);        
       TESTC1(AA, &BB,  &CC, &DD);     /* CALL TESTC1(AA,BB,CC,DD) */ 
       WK = (int) CC;                                                 
       printf(" AA= %s BB= %d CC=%d DD=%f ??/n", AA,BB,WK,DD);        
       return;                                                        
   }                                                                  

    

プログラム作成手順

手順1.モジュールの作成
省略

手順2.バインド・プログラムの作成

CRTPGM PGM(WRKLIB/TESTC) MODULE(TESTC TEST4R1 TESTCB1 TESTCL1 TESTC1) -
      DETAIL(*BASIC)



スタティック・エクスターナルを使ったデータの受渡し


モジュール間のデータ受渡しの方法として、各モジュールが外部のメモリーエリアを共通にアクセスする
という方法があります。FORTRANなどではCOMMONエリアとして早くから利用されていた方法です。
ILEの体系ではその方法が可能になっています。

COBOL

WORKING−STORAGEでEXTERNALの構造を定義します。
01項目の名前が共通外部メモリーエリアの名前になります。

       PROCESS  APOST                                             
       IDENTIFICATION DIVISION.                                   
       PROGRAM-ID.   TSTCB.                                       
       AUTHOR.                     KAJIROU.                       
       ENVIRONMENT                 DIVISION.                      
       CONFIGURATION               SECTION.                       
         SOURCE-COMPUTER.          HAL-5000.                      
         OBJECT-COMPUTER.          HAL-5000.                      
       INPUT-OUTPUT                SECTION.                       
         FILE-CONTROL.                                            
      *---------------------------------------------------------- 
       DATA                        DIVISION.                      
       WORKING-STORAGE  SECTION.                                  
       01  P       EXTERNAL.                                      
           03  AA             PIC  X(10).                         
           03  BB             PIC  S9(09)  COMP-4.                
           03  CC             PIC  S9(09)  COMP-3.                
           03  DD             COMP-2.                             
           03  EEE.                                               
               05  EE   OCCURS 3  COMP-2.                              
           03  FF             PIC  X(10).                              
      *----------------------------------------------------------
       PROCEDURE         DIVISION.                                     
       01.                                                             
           MOVE  SPACE   TO     AA.                                    
           MOVE  12345   TO     BB.                                    
           MOVE  0       TO     CC.                                    
           MOVE  0       TO     DD.                                    
       02.                                                             
           CALL  PROCEDURE  'TSTCB1'.                                  
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD            
                    ' EE1=' EE(1)  ' EE2=' EE(2) ' EE3=' EE(3).        
           DISPLAY  'FF=' FF.                                          

           CALL  PROCEDURE  'TST4R1'.                           
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD     
                    ' EE1=' EE(1)  ' EE2=' EE(2) ' EE3=' EE(3). 

           CALL  PROCEDURE  'TSTC1'.                            
           DISPLAY  'AA=' AA ' BB=' BB ' CC=' CC  ' DD=' DD     
                    ' EE1=' EE(1)  ' EE2=' EE(2) ' EE3=' EE(3). 
           DISPLAY  'FF=' FF.                                   
       03.                                                      
           STOP  RUN.                                           

サブプロシージャーでも同様にEXTERNALの構造を定義します。

       DATA                        DIVISION.                         
       WORKING-STORAGE  SECTION.                                     
       01  P       EXTERNAL.                                           
           03  AAA            PIC  X(10).                            
           03  BBB            PIC  S9(09)  COMP-4.                   
           03  CCC            PIC  S9(09)  COMP-3.                   
           03  DDD            COMP-2.                                
           03  EE.                                                   
               05  EEE  OCCURS 3  COMP-2.                            
           03  FFF            PIC  X(10).                            

RPG

ILE−RPGの場合はDS(データ構造)を定義して、EXPORTの属性をつけます。
EXPORTパラメータで名前をつければ、そちらの名前がDSの名前にに優先されます。


H  NOMAIN                                              
D P               DS                  EXPORT('P')      
D  AA                           10A                    
D  BB                           10I 0                  
D  CC                            9P 0                  
D  DD                            8F                    
D  EE                            8F   DIM(3)  
D  FF                           10A         
DTST4R1           PR                                   
PTST4R1           B                   EXPORT           
C*------------------------------------                 
C*                                                     
C                   MOVEL     'TST4R1....'  AA         
C     BB            DIV       3             BB         
C     BB            MULT      4             CC         
C     CC            DIV       5             DD         
C     BB            MULT      10            EE(1)      
C     BB            MULT      100           EE(2)      
C     BB            MULT      1000          EE(3)      
C                   MOVE      'PQRSTUVWXY'  FF
C*                                                     
C                   RETURN                             
C                   SETON                                        LR 
PTST4R1           E                                                 



extern参照の属性をもった構造(struct)を定義します。境界合わせに注意して下さい。
structのタグが外部メモリーエリアの名前になります。

   #include  <unistd.h>                                              
   #include  <decimal.h> /*  パック10進数を使うとき必要  */         
                                                                       
   void TSTC1()                                                        
   {                                                                   
   extern _Packed  struct PARM1 {                                      
      char         AA[10];                                             
      int          BB    ;                                             
      decimal(9,0) CC    ;                                             
      double       DD    ;                                             
      double       EE[3] ;                                            
      char         FF[10];                                           
                   }      P  ;    /* 外部メモリーエリア名  */ 
                                 
         
       memcpy(P.AA, "TSTC1-ABCD", 10);                                 
       memcpy(P.FF, "IJKLMNOPQR", 10);                                 
        P.BB    =  P.BB / 5 ;                                          
        P.CC    = (decimal(9,0)) (P.BB *6);                            
        P.DD    = (float) (P.CC / 7);                                  
        P.EE[2] = 0 ;                            
        P.EE[0] = (float) P.BB * 10;             
        P.EE[1] = (float) P.BB * 100;            
        P.EE[2] = (float) P.BB * 1000;           
       return;                                   
   }                                             


バインド

以上のモジュールをCRTPGMコマンドでバインドすると、プログラムができあがります。

CRTPGM  PGM(WRKLIB/TSTCB) MODULE(TSTCB TSTCB1 TST4R1 TSTC1)




目 次 へ


(C)COPYRIGHT ISHIOKA KATSUHIDE 2000