RPG

70. バインド・モジュールを使用している親PGM の再コンパイルを無くすには?

*SRVPGM はサブ・モジュールとしてiSeries400上ではDLLのような役目を果たしているという
よりは、ほとんどDLLそのものである。
しかし *SRVPGM をバインドして使用している *PGM や上位の *PGM では下位の
*SRVPGM でEXPORTしているプロシージャーが増えたりすると再コンパイルしてもう一度、
バインドしないと実行時のエラーが発生する。

そこで *SRVPGM のEXPORT関数(プロシージャー)が増えると、その *SRVPGM を使用
している*PGM*SRVPGM を探して再コンパイルしなければならない。
数が少ない場合は別としても数が多くなれば再コンパイルの漏れがあれば予測しなかった場面
で実行時のエラーが発生してしまう。

この原因はEXPORT関数が増えて再コンパイルした場合、*SRVPGM の移出記号
(シグネーチャー)が変更されてしまうからである。
DSPSRVPGM で実行キーを次々と押していくと次のような「*SIGNATURE」の画面が
表示される。これが移出記号(シグネーチャー)である。

「シグネーチャー」とは直訳すると「サイン」であるが、これはどうやらiSeries400内部での
レジストリでの CLSID として使用されているようである。
Windowsの世界でもMicrosoft社は OLEコントロールなどを作成すると自動的に「CLSID」
という識別子を内部で生成して、これをWindowsのレジストリに書き込む。
この「CLSID」によってAppの正確なありかを素早く検索できるようになっている。
「CLSID」は世界中で決して重複することがないとMicrosoft は断言している。
CD-ROM からのファイル・コピーではなく専用インストーラが必要である理由はレジストリに
CLSID を書き込む必要があるからである。

話はそれてしまったがCLSID はソースの生成時点で一回だけ生成されるがシグネーチャーは
毎回、コンパイルの都度、生成される。
従って親*PGM や親*SRVPGM ではバインドした時点のシグネーチャーとは異なるために目的
のオブジェクト(*SRVPGM) を探すことができなくて実行時エラーとなってしまうのである。
それではシグネーチャーはどのようにして決まるのであろうか?

EXPORT 定義では恐らく QSRVSRC で、次のように定義されているはずである。


   0001.00              STRPGMEXP  PGMLVL(*CURRENT)
   0002.00              EXPORT     SYMBOL("TCPSVROPEN")
   0003.00              EXPORT     SYMBOL("TCPSEND")
   0004.00              EXPORT     SYMBOL("TCPRECV")
   0005.00              EXPORT     SYMBOL("TCPCLOSE")
   0006.00              EXPORT     SYMBOL("TAKESOCKET")
   0007.00              EXPORT     SYMBOL("GIVESOCKET")
   0008.00              ENDPGMEXP
 

ここで最初の行の STRPGMEXP にカーソルを合わせて F4キーを押してみると

  
                      プログラム・エクスポート・リスト の開始  (STRPGMEXP)
   選択項目を入力して,実行キーを押してください。
  
                    追加のパラメーター
   プログラム・レベル  . . . . . . > *CURRENT      *CURRENT, *PRV
   インターフェース 識別値レベル検査   . .   *YES          *YES, *NO
   インターフェース識別値  . . . .   *GEN
   注記  . . . . . . . . . . . . .
 

のように「インターフェース識別値」「*GEN」として表示されている。
これが「犯人」である。

*GEN になっているために毎回、新たなシグネーチャーが生成されてしまう。
実はシグネーチャーは固定してしまうことができる。
最初は上記のような QSRVSRC*SRVPGM を生成させてみる。
次に DSPSRVPGM によって「*SIGNATURE」の画面を表示してシグネーチャーの値を
コピーしておく。
次に QSRVSRC を次のようにシグネーチャーをペーストして明示的に指定する。


   0001.00              STRPGMEXP  PGMLVL(*CURRENT) +
   0001.01                           SIGNATURE(X'0000000D5C5B8C16AF2563B16605EAF+
   0001.02                           7')
   0002.00              EXPORT     SYMBOL("TCPSVROPEN")
   0003.00              EXPORT     SYMBOL("TCPSEND")
   0004.00              EXPORT     SYMBOL("TCPRECV")
   0005.00              EXPORT     SYMBOL("TCPCLOSE")
   0006.00              EXPORT     SYMBOL("TAKESOCKET")
   0007.00              EXPORT     SYMBOL("GIVESOCKET")
   0008.00              ENDPGMEXP
 

HEX で指定していることに注意されたい。
これで CRTSRVPGM を行うとシグネーチャーは変更されることはないので
EXPORTプロシージャーが増えてもうっかり再コンパイルを忘れた上位*PGM なども
実行時エラーになることはない。
品質に優れたソフトウェア製品の開発などには是非考慮したい工夫である。