*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 なども
実行時エラーになることはない。
品質に優れたソフトウェア製品の開発などには是非考慮したい工夫である。