RTNPARM

RTNPARM キーワードは、プロシージャーの戻り値が、 参照によって渡される、 定義済みの戻り値と同じタイプのパラメーターとして内部的に処理されることを指定します。

RTNPARM を使用すると、大きな値を戻す場合にパフォーマンスが向上する可能性があります。

RTNPARM キーワードによるパフォーマンスへの影響は、小さなマイナスの影響から、大きなプラスの影響までさまざまです。 プロトタイプ化された戻り値が、整数や小さいデータ構造などのように比較的小さい場合には、小さなマイナスの影響が出る可能性があります。 プロトタイプ化された戻り値が、32767 バイトのデータ構造などのように、大きい値の場合にはパフォーマンスは多少向上します。 プロトタイプ化された戻り値が大きい可変長ストリングで、実際に戻された値が比較的小さい場合に、パフォーマンスの向上が最も顕著になります。 例えば、プロトタイプで戻り値を 1,000,000 バイトの可変長文字ストリングとして定義していて、値 「abc」が戻されるような場合です。

プロシージャー・プロトタイプに RTNPARM を使用すると、そのプロシージャーの呼び出しを含む他のプロシージャーに必要な自動記憶域の量が減る場合もあります。 例えば、プロシージャー MYCALLER に、大きな値を戻すプロシージャー MYPROC の呼び出しが含まれている場合、 プロシージャー MYCALLER は、(MYCALLER が実行時にプロシージャー MYPROC を実際に呼び出さなくても) 追加の自動記憶域を必要とします。 場合によっては、必要な自動記憶域が多すぎるために、プロシージャー MYCALLER がコンパイルされなくなります。また、呼び出しスタックの合計自動記憶域が最大限度を超えてしまい、MYCALLER を呼び出せなくなることもあります。 RTNPARM を使用すると、追加の自動記憶域によるこの問題が回避されます。

注:
  1. 追加のパラメーターは、最初のパラメーターとして渡されます。
  2. %PARMS 組み込み関数と %PARMNUM 組み込み関数のパラメーター・カウントには、追加のパラメーターが含まれます。 RTNPARM キーワードが指定されると、%PARMNUM によって戻される値は、見かけ上のパラメーター番号より 1 つ大きくなります。
  3. パラメーター番号を必要とする API (CEEDOD または CEETSTA など) を呼び出すときには、 追加の最初のパラメーターを考慮してください。 例えば、プロシージャーに 3 つのパラメーターがあり、パラメーター・リストで 3 番目に出現するパラメーターの長さを取得したい場合には、 4 番目のパラメーターについて情報を要求します。 %PARMNUM 組み込み関数を使用してこれらの API を呼び出すための正しいパラメーター番号を戻す場合には、 正しいパラメーター番号を手動で決定する必要はありません。
  4. 呼び出し元のプロシージャーが RPG 以外の言語で作成されている場合、 呼び出し元では、プロシージャーに戻り値がなく、 RPG の戻り値と同じタイプの、参照によって渡される追加の最初のパラメーターがあるものとして、呼び出しをコーディングする必要があります。
  5. 同様に、呼び出し先のプロシージャーが RPG 以外の言語で作成されている場合、 そのプロシージャーは戻り値なしで、RPG の戻り値と同じタイプの、参照によって渡される追加の最初のパラメーターがある状態としてコーディングする必要があります。
  6. RTNPARM がプロシージャーに指定された場合、プロトタイプ・パラメーターの最大数は 398 です。
  7. RTNPARM キーワードは、Java™ メソッド呼び出しには使用できません。

RTNPARM キーワードは、プロトタイプ定義とプロシージャー・インターフェース定義の両方に適用されます。

図 1. RTNPARM キーワードを指定したプロシージャーの例
1. プロシージャーのプロトタイプ
D center          pr        100000a   varying
D                                     rtnparm
D   text                     50000a   const varying
D   len                         10i 0 value


2. プロシージャーの呼び出し
D title           s            100a   varying
 /free
    title = center ('Chapter 1' : 20);
    // title = '     Chapter 1     '

3. プロシージャー
P center          b                   export
D center          pi        100000a   varying
D                                     rtnparm
D   text                     50000a   const varying
D   len                         10i 0 value
D blanks          s          50000a   inz(*blanks)
D numBlanks       s             10i 0
D startBlanks     s             10i 0
D endBlanks       s             10i 0
 /free
    if len < %len(text);
       ... handle invalid input
    endif;
    numBlanks = len - %len(text);
    startBlanks = numBlanks / 2;
    endBlanks = numBlanks - startBlanks;
    return %subst(blanks : 1 : startBlanks)
         + text
         + %subst(blanks : 1 : endBlanks);
 /end-free
P center          e
図 2. RTNPARM キーワードを指定した %PARMS の使用と CEEDOD の呼び出し
D proc            pi              a   len(16773100) varying
D                                     rtnparm opdesc
D   p1                          10a
D   p2                          10a   options(*varsize)
D   p3                          10a   options(*omit : *nopass)

D num_parms       s             10i 0
D parm_len        s             10i 0
D desc_type       s             10i 0
D data_type       s             10i 0
D desc_info1      s             10i 0
D desc_info2      s             10i 0
D CEEDOD          pr
D   parm_num                    10i 0 const
D   desc_type                   10i 0
D   data_type                   10i 0
D   desc_info1                  10i 0
D   desc_info2                  10i 0
D   parm_len                    10i 0
D   feedback                    12a   options(*omit)
 /free
    // Get information about parameter p2
    callp CEEDOD(%parmnum(p2) : desc_type : data_type
               : desc_info1 : desc_info2
               : parm_len : *omit);
    if parm_len < 10;
       // The parameter passed for p2 is shorter than 10
    endif;

    // Find out the number of parameters passed
    num_parms = %parms();
    // If all three parameters were passed, num_parms = 4

    // test if p3 was passed
    if num_parms >= %parmnum(p3);
       // Parameter p3 was passed
       if %addr(p3) <> *null;
          // Parameter p3 was not omitted
       endif;
    endif;
図 3. 別の言語からの RTNPARM キーワードを指定したプロシージャーの呼び出し
1. RPG プロトタイプ

D myproc          pr           200a   rtnparm
D   name                        10a   const

2. この RPG プロシージャーを呼び出す CL モジュール

dcl &retval type(*char) len(200)

callprc myproc parm(&retval 'Jack Smith')
図 4. 別の言語で作成された RTNPARM キーワードを指定したプロシージャーの呼び出し
1. CL プロシージャー GETLIBTEXT

PGM PARM(&retText &lib)

DCL &retText type(*char) len(50)
DCL &lib     type(*char) len(10)

/* Set &retText to the library text */
rtvobjd obj(&lib) objtype(*lib) text(&retText)
return

2. RTNPARM キーワードを使用してこの CL プロシージャーを呼び出す RPG プロシージャー

D getLibText      pr            50a   rtnparm
D   name                        10a   const
 /free
      if getLibText('MYLIB') = *blanks;
          ...