さてサブ・ルーチンをプロシージャーに置換えたのた再利用が目的である。
ILE-RPGのプロシージャーとは一般の開発言語での「関数」であり
再利用を目的としている。
JavaやVS++でのClassに相当する。VBやVBAの関数と同じ概念が
ILE-RPGのプロシージャーである。
それでは前回使ったTESTPROCのプロシージャー: SNDPGMMSG を
公開してみよう。
[プロシージャー: TESTPROC ]
ソースはこちらから
0001.00 H DFTNAME(TESTPROC) DATEDIT(*YMD/) BNDDIR('QC2LE') 0002.00 F********** プロシージャーのテスト ************************************ 0003.00 F* 0004.00 F********************************************************************** 0005.00 0006.00 * CRTRPGMOD OBJ(QTEMP/TESTPROC) SRCFILE(R610SRC/QRPGLESRC) 0007.00 * DBGVIEW(*SOURCE) AUT(*ALL) 0008.00 * CRTPGM PGM(ASNET.COM/TESTPROC) MODULE(QTEMP/TESTPROC ACTGRP(*NEW) 0009.00 * AUT(*ALL) 0010.00 0011.00 *-------------------------------------------------------------------* 0012.00 * 2020/08/08 : 作成 0013.00 *-------------------------------------------------------------------* 0014.00 *( 作業変数 ) 0015.00 D MSR S 80 DIM(1) CTDATA PERRCD(1) 配列 0016.00 D AR S 1A DIM(256) 0017.00 D N S 4S 0 0018.00 0019.00 D*( SNDPGMMSG のプロトタイプ宣言 ) 0020.00 D SNDPGMMSG PR 0021.00 D MSG 3000A Value 0022.00 D MSGTYPE_IN 10A value OPTIONS(*NOPASS) 0023.00 D CALLSTACKC_IN 10I 0 CONST OPTIONS(*NOPASS) 0024.00 0025.00 C*( メイン・ルーチンの始まり ) 0026.00 C CALLP SNDPGMMSG(MSR(1)) 0027.00 C SETON LR 0028.00 C RETURN 0029.00 C*( メイン・ルーチンの終わり ) 0030.00 0031.00 C****************************************************** 0032.00 C *INZSR BEGSR 0033.00 C****************************************************** 0034.00 C* 初期 CYCLE のみの実行 0035.00 C ENDSR 0036.00 ********************************************************* 0037.00 * SNDPGMMSG: メッセージを現在の CALLSTACK に送信 * 0038.00 ********************************************************* 0039.00 *---( SNDPGMMSG PROCEDURE ここから )------------------------* 0040.00 P SNDPGMMSG B EXPORT 0041.00 D PI 0042.00 D MSG 3000A Value 0043.00 D MSGTYPE_IN 10A value OPTIONS(*NOPASS) 0044.00 D CALLSTACKC_IN 10I 0 CONST OPTIONS(*NOPASS) 0045.00 0046.00 D APIERR DS 0047.00 D GETBYT 1 4B 0 INZ(160) 0048.00 D AVLBYT 5 8B 0 INZ(0) 0049.00 D MSGID 9 15 0050.00 D MSGDTA 17 160 0051.00 0052.00 D QMHSNDPM PR ExtPgm('QMHSNDPM') 0053.00 D MSGID 7A CONST 0054.00 D MSGFILE 20A CONST 0055.00 D MSGDATA 6000A CONST OPTIONS(*varsize) 0056.00 D MSGDATALEN 10I 0 CONST 0057.00 D MSGTYPE 10A CONST 0058.00 D CALLSTACKE 10A CONST 0059.00 D CALLSTACKC 10I 0 CONST 0060.00 D MSGKEY 4A 0061.00 D APIERR LIKEDS(APIERR) 0062.00 D OPTIONS(*VARSIZE) 0063.00 D PARMS S 4S 0 0064.00 D MSGKEY S 4A 0065.00 D CALLSTACKC S 10I 0 INZ(1) 0066.00 D MSGTYPE S 10A INZ('*DIAG ') 0067.00 0068.00 C EVAL PARMS = %PARMS() 0069.00 C SELECT 0070.00 C WHEN PARMS = 1 0071.00 C WHEN PARMS = 2 0072.00 C EVAL MSGTYPE = MSGTYPE_IN 0073.00 C WHEN PARMS = 3 0074.00 C EVAL CALLSTACKC = CALLSTACKC_IN 0075.00 C EVAL MSGTYPE = MSGTYPE_IN 0076.00 C ENDSL 0077.00 /FREE 0078.00 QMHSNDPM('CPF9897':'QCPFMSG *LIBL':MSG: 0079.00 %LEN(%TRIM(MSG)):MSGTYPE:'*PGMBDY': 0080.00 CALLSTACKC:MSGKEY:APIERR); 0081.00 /END-FREE 0082.00 C RETURN 0083.00 P E 0084.00 *---( SNDPGMMSG PROCEDURE ここまで )------------------------* 0085.00 0086.00 ** MSR -- 以下は配列 0087.00 これはメッセージ送信のテストです。
[解説]
最初に CRTBNDRPG ではなく CRTRPGMOD (RPG モジュールの作成)によって
次のようにコンパイルする。
CRTRPGMOD MODULE(QTEMP/TESTPROC) SRCFILE(R610SRC/QRPGLESRC) DBGVIEW(*SOURCE) AUT(*ALL)
これでライブラリーQTEMPにモジュール: TESTPROC (*MODULE)が作成される。
次にサービス・プログラム(*SRVPGM)を作成するのだがそれにはサービス・ソースが
必要となるので
CRTSRCPF FILE(SRCLIB/QSRVSRC) IGCDTA(*YES) CCSID(65535) AUT(*ALL)
のようにして事前にバインド・ソース・ファイル: QSRVSRC を作成しておいて
SEU で次のようなソース・メンバーを最初に作成する。
SEU の編集ソース・タイプは BND としておくこと。
[メンバー: TESTPROC ]
ソースはこちらから
0001.00 STRPGMEXP SIGNATURE(*GEN) 0002.00 EXPORT SYMBOL("SNDPGMMSG") 0003.00 ENDPGMEXP
[解説]
0001.00 STRPGMEXP SIGNATURE(*GEN)
のシグニチャー(識別子)は最初の作成では *GEN としておくとコンパイラーが
全世界中で重複することのない識別子を自動生成してくれるので
自分で命名するよりはコンパイラーに識別子の発生を任せるほうがよい。
これはWindowsでも同じことをやっていてこれから作成しようとするサービス・プログラム
(*SRVPGM)とはWindowsの DLLに相当する。
Windowsでは同じように識別子が世界中で絶対に重複することのない識別子が自動的に派生されて
登録される。
その識別子がWindowsのレジストリに登録されて呼び出すときはレジストリの識別子を
読んでそのDLLがWindowsのディレクトリの登録簿を読み出してプログラムを起動する仕組みに
なっている。
従ってモジュールの導入でインストーラはレジストリへの登録もやっているので
コピーしただけでは駄目なのはインストーラによるレジストリへの登録が必要だからである。
IBM iの場合も恐らくはWindowsと同じことを内部でやっているものと思われる。
このソースが登録できたら次は CRTSRVPGM(サービス・プログラムの作成)によって
次のようにサービス・プログラムを作成する。
CRTSRVPGM SRVPGM(OBJLIB/TESTPROC) MODULE(QTEMP/TESTPROC) SRCFILE(SRCLIB/QSRVSRC) AUT(*ALL)
作成できたら
DSPSRVPGM OBJLIB/TESTPROC
で表示してみて欲しい。
サービス・プログラム情報の表示 画面 10 の 1 サービス・プログラム . . . . . . . . . . : TESTPROC ライブラリー . . . . . . . . . . . . . : OBJLIB 所有者 . . . . . . . . . . . . . . . . . : QTR サービス・プログラム属性 . . . . . . . . : RPGLE 詳細 . . . . . . . . . . . . . . . . . . : *BASIC サービス・プログラム作成情報 : サービス・プログラム作成日/時刻 . . . . . . . . : 20/08/09 05:56:34 エクスポート・ソース・ファイル . . . . . . . . . : QSRVSRC ライブラリー . . . . . . . . . . . . . . . . . : R610SRC エクスポート・メンバー . . . . . . . . . . . . . : TESTPROC 活動化グループ属性 . . . . . . . . . . . . . . . : *CALLER 共用活動化グループ . . . . . . . . . . . . . . . : *NO 現行エクスポート記号 . . . . . . . . . . . . . . : 00000000000000C7E2D4D4C7 7C4D5E2 ユーザー・プロファイル . . . . . . . . . . . . . : *USER 続く ... 続行するには,実行キーを押してください。 F3= 終了 F11= 文字 インターフェース 識別値の表示 F12= 取り消し
何回か実行キーを押して進めていくと次の画面が表示される。
サービス・プログラム情報の表示 画面 10 の 9 サービス・プログラム . . . . . . . . . . : TESTPROC ライブラリー . . . . . . . . . . . . . : TEST.COM 所有者 . . . . . . . . . . . . . . . . . : QTR サービス・プログラム属性 . . . . . . . . : RPGLE 詳細 . . . . . . . . . . . . . . . . . . : *SIGNATURE 記号 : 00000000000000C7E2D4D4C7D7C4D5E2 終わり F3= 終了 F11= 文字 インターフェース 識別値の表示 F12= 取り消し F17= 先頭 F18= 最後
これがコンパイラーによって生成された世界中に重複のない識別コードであるので
この識別コード(記号)をコピーしておく。
次に バインド・ソースをSEUでオープンして
PGM エクスポート・リスト開始 (STRPGMEXP) 選択項目を入力して,実行キーを押してください。 追加のパラメーター プログラム・レベル . . . . . . *CURRENT *CURRENT, *PRV インターフェース・シグニチャー・レベル 検査 . . *YES *YES, *NO シグニチャー . . . . . . . . . > X'00000000000000C7E2D4D4C7D7C4D5E2' 注記 . . . . . . . . . . . . . 終り F3= 終了 F4=プロンプト F5= 最新表示 F12= 取り消し F13= この画面の使用法 F24= キーの続き
のようにして X’の後ろに貼り付ける。
結果としてバインド・ソースは次のようになる。
0001.00 STRPGMEXP SIGNATURE(X'00000000000000C7E2D4D4C7D7C4D5E2') 0002.00 EXPORT SYMBOL("SNDPGMMSG") 0003.00 ENDPGMEXP
[解説]
バインド・ソースを保管したらもう一度
CRTSRVPGM SRVPGM(OBJLIB/TESTPROC) MODULE(QTEMP/TESTPROC) SRCFILE(SRCLIB/QSRVSRC) AUT(*ALL)
を行ってサービス・プログラム(*SRVPGM)を再作成する。
バインド・ソースは最初に *GEN と指定しておいたので *GEN のままでは
サービス・プログラム(*SRVPGM)を再作成するたびに新しい識別子が生成されてしまう。
このサービス・プログラム(*SRVPGM)をバインドして利用する上位のプログラムは
識別子によってサービス・プログラムをバインドするので識別子が変わってしまったのでは
上位のプログラムも再作成しないと動作できなくなってしまう。
従って最初に*GENで生成したら生成された識別子をバインド・ソースに登録しておいて
以降は同じ識別子で再作成されるようにしておかなければならない。
もう一度
DSPSRVPGM OBJLIB/TESTPROC
で表示してみると
サービス・プログラム情報の表示 画面 10 の 5 サービス・プログラム . . . . . . . . . . : TESTPROC ライブラリー . . . . . . . . . . . . . : TEST.COM 所有者 . . . . . . . . . . . . . . . . . : QTR サービス・プログラム属性 . . . . . . . . : RPGLE 詳細 . . . . . . . . . . . . . . . . . . : *PROCEXP プロシージャーのエクスポート : プロシージャー名 ARGOPT SNDPGMMSG *NO 終わり F3= 終了 F12= 取り消し F17= 先頭 F18= 最後
のようにプロシージャー: SNDPGMMSG が公開(EXPORT)されていることがわかる。
次回はこのプロシージャーを上位プログラムから呼び出して使用する方法について
解説する。