バージョン 6.3.3
 —  ステートメント  —

CALL

CALL [INTERFACE4] operand1 [USING] [operand2] ... 128

このドキュメントでは、次のトピックについて説明します。

構文図で使用されている記号については、「構文記号」を参照してください。

関連ステートメント:CALL FILE | CALL LOOP | CALLNAT | DEFINE SUBROUTINE | ESCAPE | FETCH | PERFORM

関連機能グループ:「プログラムおよびルーチンの呼び出し


機能

CALL ステートメントは、Natural プログラムから他の標準プログラミング言語で書かれた外部プログラムまたは関数を呼び出し、CALL の次のステートメントに戻します。

呼び出される側のプログラムまたは関数は、標準 CALL インターフェイスをサポートするプログラミング言語で書くことができます。 1 つ以上の外部プログラムまたは関数を呼び出すために、複数の CALL ステートメントを指定できます。

Top of page

構文説明

オペランド定義テーブル:

オペランド 構文要素 フォーマット ステートメント参照 ダイナミック定義
operand1 C S       A                         不可
operand2 C S A G   A U N P I F B D T L C G  

構文要素の説明:

INTERFACE4 オプションのキーワード INTERFACE4 は、外部プログラムのコールに使用するインターフェイスのタイプを指定します。 下記の INTERFACE4 を参照してください。
operand1
呼び出される関数の名前:

呼び出される関数の名前(operand1)は、定数または変数で指定できます。プログラムロジックによって呼び出す関数が異なる場合は、長さ 1~8 の英数字の変数として指定します。 変数では、関数名を左詰めで指定する必要があります。

[USING] operand2
パラメータ:

CALL ステートメントでは、パラメータ(operand2)を 128 個まで指定できます。 指定する各パラメータフィールドごとに、1 つのアドレスがパラメータリストで渡されます。

グループ名を使用した場合、そのグループは個々のフィールドに変換されます。つまり、ユーザーがグループの開始アドレスを指定したい場合、グループの最初のフィールドを指定する必要があります。

注意:
アプリケーション独立変数(AIV)またはコンテキスト変数をパラメータとしてユーザー出口に渡す場合、そのユーザー出口が新しい AIV またはコンテキスト変数を作成する Natural サブプログラムを呼び出すと、そのパラメータはサブプログラムから戻った後で不正になります。 これは、新しい AIV またはコンテキスト変数がサブプログラム自体、またはサブプログラムから直接または間接的に呼び出された別のオブジェクトで作成されるかどうかに関わらず当てはまります。

Top of page

リターンコード

呼び出された関数のコンディションコードは、Natural システム関数 RET(リターンコード関数)で取得できます。

例:

... 
RESET #RETURN(B4) 
CALL 'PROG1' 
IF RET ('PROG1') > #RETURN 
  WRITE 'ERROR OCCURRED IN PROGRAM1' 
END-IF 
...

Top of page

ユーザー出口

CALL ステートメントで呼び出される外部関数にアクセスできるようにするには、ユーザー出口が必要です。 ユーザー出口は、DLL(ダイナミックリンクライブラリ)内に配置する必要があります。 ユーザー出口の詳細については、次のファイルを参照してください。

%NATDIR%\%NATVERS%\natural\samples\sysexuex\readme.txt

readme.txt ファイルを参照するには、Natural のインストール時にサンプル機能を選択する必要があります。

Top of page

INTERFACE4

INTERFACE4 キーワードでは、外部プログラムのコールに使用するインターフェイスのタイプを指定します。 このキーワードはオプションです。 このキーワードを指定する場合は、インターフェイスを "Interface4" として定義し、外部プログラムのコールに使用します。

次の表に、INTERFACE4 を使用した場合と、INTERFACE4 使用しなかった場合の CALL ステートメントの違いを示します。

  キーワード INTERFACE4 を使用しない CALL ステートメント キーワード INTERFACE4 を使用する CALL ステートメント
使用可能なパラメータ数 128 32767
1 つのパラメータの最大データサイズ 64 K 1 GB
配列情報の取得
ラージオペランドとダイナミックオペランドのサポート
API 経由でのパラメータアクセス

以下では次のトピックについて説明します。

INTERFACE4 - 外部 3GL プログラムインターフェイス

外部 3GL プログラムのインターフェイスは、Natural の CALL ステートメントで INTERFACE4 を指定するときに、次のように定義します。

NATFCT functionname (numparm, parmhandle, traditional)
USR_WORD numparm; 転送するオペランド(operand2)の総数が格納される 16 ビット unsigned short 型整数。
void *parmhandle; 構造体を渡すパラメータへのポインタ。
void *traditional; インターフェイスタイプのチェックに使用します(NULL ポインタでない場合は通常の CALL インターフェイス)。

INTERFACE4 のオペランド構造体

INTERFACE4 のオペランド構造体の名前は、"parameter_description" で次のように定義します。 構造体は、ヘッダーファイル natuser.h とともに提供されます。

struct parameter_description
void * address パラメータデータのアドレス。不整列。realloc() および free() は使用できません。
int format フィールドデータフォーマット:NCXR_TYPE_ALPHA など(natuser.h)。
int length 長さ(小数点以上、該当する場合)。
int precision 小数点以下の長さ(該当する場合)。
int byte_length dimensions の整数値のバイト単位のフィールドの長さ(0~IF4_MAX_DIM)。
int dimensions 次元の数(0~IF4_MAX_DIM)。
int length_all 配列のデータ長の合計(バイト単位)。
int flags ビットごとに OR で結合したフラグビットは次のとおりです。
IF4_FLG_PROTECTED: パラメータは書き込み保護されています。
IF4_FLG_DYNAMIC: パラメータはダイナミック変数です。
IF4_FLG_NOT_CONTIGUOUS: 配列の要素が隣接していません(要素間に空白があります)。
IF4_FLG_AIV: このパラメータはアプリケーション独立変数です。
IF4_FLG_DYNVAR: パラメータはダイナミック変数です。
IF4_FLG_XARRAY: パラメータは x-array です。
IF4_FLG_LBVAR_0: 次元 0 の下限は可変です。
IF4_FLG_UBVAR_0: 次元 0 の上限は可変です。
IF4_FLG_LBVAR_1: 次元 1 の下限は可変です。
IF4_FLG_UBVAR_1: 次元 1 の上限は可変です。
IF4_FLG_LBVAR_2: 次元 2 の下限は可変です。
IF4_FLG_UBVAR_2: 次元 2 の上限は可変です。
int occurrences[IF4_MAX_DIM] 各次元における配列のオカレンス。
int indexfactors[IF4_MAX_DIM] 各次元の配列インデックスファクタ。
void * dynp 内部使用に予約済み。
void * pops 内部使用に予約済み。

アドレス要素は、ダイナミック変数の配列および x-array に対してヌルです。 この場合、配列データは全体としてアクセスすることはできませんが、下記のパラメータアクセス機能でアクセスする必要があります。

固定長の変数の固定範囲の配列に対して、配列の内容はアドレス要素を使用してダイレクトにアクセスすることができます。 この場合、配列要素(i,j,k)のアドレスは以下のように計算されます(特に配列要素が連続していない場合)。

elementaddress = address + i * indexfactors[0] + j * indexfactors[1] + k * indexfactors[2] 

配列の次元数が 3 次元よりも小さい場合は、最後の項が除外されます。

INTERFACE4 - パラメータアクセス

パラメータのアクセスに使用する機能の集合があります。 処理フローは次のとおりです。

3GL プログラムから任意のサブプログラムをコールすために、新規パラメータセットを作成し、初期化する機能もあります。 この機能を使用して、3GL プログラムがメモリを上書きしないようにするために、パラメータのアクセスが保証されます (Natural データは安全で、メモリは 3GL プログラムのデータ内を上書きすることはまだ可能です)。

エクスポート機能

以下では次のトピックについて説明します。

パラメータ情報の取得

この機能は、任意のパラメータから必要な情報をすべて受け取るために、3GL プログラムで使用します。 情報は、struct parameter_description上記を参照)に返されます。

プロトタイプ:

int ncxr_get_parm_info ( int parmnum, void *parmhandle, struct parameter_description *descr );

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle 内部パラメータ構造へのポインタ
descr struct parameter_description のアドレス
return 戻り値: 情報:
0 OK
-1 無効なパラメータ番号。
-2  内部エラーが発生しました。
-7 インターフェイスバージョンの競合。

パラメータデータの取得

この機能は、任意のパラメータからデータを取得するために、3GL プログラムで使用します。

Natural は、指定したパラメータ番号でパラメータを識別し、指定したバッファサイズのアドレスにパラメータデータを書き出します。

パラメータデータが指定したバッファサイズより長い場合、Natural は指定した長さにそのデータを切り捨てます。 外部 3GL プログラムは ncxr_get_parm_info 関数を、パラメータデータの長さを要求するために使用することができます。

パラメータデータを取得する関数は 2 つあり、ncxr_get_parm はパラメータ全体を取得し(パラメータが配列の場合でも)、ncxr_get_parm_array 関数は特定の配列要素を取得します。

(ダイナミックまたはスタティックな)3GL プログラムにより、指定したサイズのメモリが "バッファ" に対して割り当てられない場合、予期できない結果になることがあります。 Natural では NULL ポインタのチェックだけが実行されます。

タイプ I2/I4/F4/F8 の変数で、データが切り取られる場合(バッファ長がパラメータの合計長と等しくない)、その結果はマシンのタイプにより異なります(リトルエンディアン/ビッグエンディアン)。 アプリケーションによっては、反復を可能にするために、スタティックデータを使用しないようにユーザー出口をプログラムする必要があります。

プロトタイプ:

int ncxr_get_parm( int parmnum, void *parmhandle, int buffer_length, void *buffer ) int ncxr_get_parm_array( int parmnum, void *parmhandle, int buffer_length, void *buffer, int *indexes ) 

This function is identical to ncxr_get_parm, except that the indexes for each dimension can be specified. 未使用次元のインデックスは 0 として指定しておく必要があります。

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle 内部パラメータ構造へのポインタ
buffer_length 要求したデータを書き出す必要のあるバッファの長さ。
buffer 要求したデータを書き出す必要のあるバッファのアドレス。 このバッファは I2/I4/F4/F8 変数にアクセスしやすいように配置しておく必要があります。
indexes インデックス情報をもつ配列
return 戻り値: 情報:
< 0 情報検索時のエラーを示します。
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-3 データは切り捨てられました。
-4 データが配列ではありません。
-7 インターフェイスバージョンの競合。
-100 次元 0 のインデックスが範囲外です。
-101 次元 1 のインデックスが範囲外です。
-102 次元 2 のインデックスが範囲外です。
0 操作に成功しました。
> 0 正常に行われましたが、(バッファの方がデータよりも長かったため)データの長さはこのバイト数になりました。

オペランドデータの書き戻し

この機能は、任意のパラメータへデータを戻すために、3GL プログラムで使用します。 Natural では、指定したパラメータ番号でパラメータを識別し、指定したバッファサイズとアドレスからパラメータデータを書き出します。 パラメータデータが指定したバッファサイズより小さい場合、データはパラメータデータの長さに切り捨てられます。つまり、バッファの残りは無視されます。 パラメータデータが指定したバッファサイズより大きい場合、データは指定したバッファ長だけコピーされます。パラメータの残りはそのままです。 これは、配列にも同様に当てはまります。 パラメータとしてのダイナミック変数については、パラメータのサイズが指定したバッファ長に変更されます。

タイプ I2/I4/F4/F8 の変数で、データが切り取られる場合(バッファ長がパラメータの合計長と等しくない)、その結果はマシンのタイプにより異なります(リトルエンディアン/ビッグエンディアン)。 アプリケーションによっては、反復を可能にするために、スタティックデータを使用しないようにユーザー出口をプログラムする必要があります。

プロトタイプ:

int ncxr_put_parm ( int parmnum, void *parmhandle, int buffer_length, void *buffer ); int ncxr_put_parm_array ( int parmnum, void *parmhandle, int buffer_length, void *buffer, int *indexes );

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle 内部パラメータ構造体を指すポインタ。
buffer_length データを送るバッファのバッファアドレスを元に複写するためのデータの長さ。
indexes インデックス情報。
return
戻り値: 情報:
< 0 情報複写時のエラーを示します。
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-3 指定したデータが多すぎます。 パラメータの長さで複写されました。
-4 パラメータが配列ではありません。
-5 パラメータは保護されています(定数または AD=O)。
-6 "メモリ不足" により、ダイナミック変数のサイズを変更できませんでした。
-7 インターフェイスバージョンの競合。
-13 指定したバッファに、不完全な Unicode 文字が含まれています。
-100 次元 0 のインデックスが範囲外です。
-101 次元 1 のインデックスが範囲外です。
-102 次元 2 のインデックスが範囲外です。
0 操作に成功しました。
> 0 正常に行われましたが、パラメータ長が指定された長さを超えていたため、パラメータの長さはこのバイト数になりました。

パラメータセットの作成、初期化、削除

3GL プログラムが Natural サブプログラムを呼び出すには、サブプログラムが予期しているパラメータに対応するパラメータセットを構築する必要があります。 関数 ncxr_create_parm を使用して、ncxr_if_callnat へのコールで渡すパラメータセットを作成します。 作成されたパラメータセットは、CALL INTERFACE4 ステートメントで 3GL プログラムに渡されるパラメータセットのように、opaque パラメータハンドルによって表されます。 したがって、上記のように、新しく作成したパラメータセットは関数 ncxr_put_parm* および ncxr_get_parm* で操作することができます。

新しく作成したパラメータセットは、関数 ncxr_create_parm を呼び出した後は、まだ初期化されていません。 個々のパラメータは下記の ncxr_parm_init* 関数のセットによって特定データタイプに初期化されます。 その後、関数 ncxr_put_parm* および ncxr_get_parm* は個々のパラメータの内容にアクセスするために使用されます。 呼び出す側がパラメータセットを終了した後、それらはパラメータハンドルを削除する必要があります。 したがって、ncxr_if4_callnat を通して呼び出されるサブプログラムのパラメータセットの作成と使用の一般的なシーケンスは、次のようになります。

ncxr_create_parm
ncxr_init_ parm*
ncxr_init_ parm*
...
ncxr_put_ parm*
ncxr_put_ parm*
...
ncxr_get_parm_info*
ncxr_get_parm_info*
...
ncxr_if4_callnat
...
ncxr_get_parm_info*
ncxr_get_parm_info*
...
ncxr_get_ parm*
ncxr_get_ parm*
...
ncxr_delete_parm

パラメータセットの作成

関数 ncxr_create_parm を使用して、ncxr_if_callnat へのコールで渡すパラメータセットを作成します。

プロトタイプ:

int ncxr_create_parm( int parmnum, void** pparmhandle )

パラメータの説明:

parmnum 作成するパラメータの数。
pparmhandle 作成されたパラメータハンドルへのポインタ。
return 戻り値: 情報:
< 0 エラー:
-1 パラメータカウントが不正です。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
0 操作に成功しました。

パラメータセットの削除

ncxr_create_parm で作成されたパラメータセットを削除するには、関数 ncxr_delete_parm を使用します。

プロトタイプ:

int ncxr_delete_parm( void* parmhandle )

パラメータの説明:

parmhandle 削除するパラメータハンドルへのポインタ。
return 戻り値: 情報:
< 0 エラー:
-2 内部エラーが発生しました。
0 操作に成功しました。

スタティックデータタイプのスカラの初期化

プロトタイプ:

int ncxr_init_parm_s( int parmnum, void *parmhandle, char format, int length, int precision, int flags );

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle パラメータハンドルへのポインタ。
format パラメータのフォーマット。
length パラメータの長さ。
precision パラメータの精度。
flags フラグの組み合わせ。

IF4_FLG_PROTECTED

return 戻り値: 情報:
< 0 エラー:
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
-8 フォーマットが正しくありません。
-9 無効な長さまたは精度。
0 操作に成功しました。

スタティックデータタイプの配列の初期化

プロトタイプ:

int ncxr_init_parm_sa( int parmnum, void *parmhandle, char format, int length, int precision, int dim, int *occ, int flags ); 

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle パラメータハンドルへのポインタ。
format パラメータのフォーマット。
length パラメータの長さ。
precision パラメータの精度。
dim 配列の次元。
occ 次元ごとのオカレンス数。
flags フラグの組み合わせ。

IF4_FLG_PROTECTED
IF4_FLG_LBVAR_0
IF4_FLG_UBVAR_0
IF4_FLG_LBVAR_1
IF4_FLG_UBVAR_1
IF4_FLG_LBVAR_2
IF4_FLG_UBVAR_2

return 戻り値: 情報:
< 0 エラー:
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
-8 フォーマットが正しくありません。
-9 無効な長さまたは精度。
-10 無効な次元数。
-11 変数制限の無効な組み合わせ。
0 操作に成功しました。

ダイナミックデータタイプのスカラの初期化

プロトタイプ:

int ncxr_init_parm_d( int parmnum, void *parmhandle, char format, int flags );

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle パラメータハンドルへのポインタ。
format パラメータのフォーマット。
flags フラグの組み合わせ。

IF4_FLG_PROTECTED

return 戻り値: 情報:
< 0 エラー:
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
-8 フォーマットが正しくありません。
0 操作に成功しました。

ダイナミックデータタイプの配列の初期化

プロトタイプ:

int ncxr_init_parm_da( int parmnum, void *parmhandle, char format, int dim, int *occ, int flags );

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle パラメータハンドルへのポインタ。
format パラメータのフォーマット。
dim 配列の次元。
occ 次元ごとのオカレンス数。
flags フラグの組み合わせ。

IF4_FLG_PROTECTED
IF4_FLG_LBVAR_0
IF4_FLG_UBVAR_0
IF4_FLG_LBVAR_1
IF4_FLG_UBVAR_1
IF4_FLG_LBVAR_2
IF4_FLG_UBVAR_2

return 戻り値: 情報:
< 0 エラー:
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
-8 フォーマットが正しくありません。
-10 無効な次元数。
-11 変数制限の無効な組み合わせ。
0 操作に成功しました。

X-array パラメータのサイズ変更

プロトタイプ:

int ncxr_resize_parm_array( int parmnum, void *parmhandle, int *occ ); 

パラメータの説明:

parmnum パラメータの順序を表す番号。 これにより、渡されたパラメータリストのパラメータが識別されます。 範囲:0 ~ numparm-1。
parmhandle パラメータハンドルへのポインタ。
occ 次元当たりの新規オカレンス数。
return 戻り値: 情報:
< 0 エラー:
-1 無効なパラメータ番号。
-2 内部エラーが発生しました。
-6 メモリ不足の状態です。
-12 オペランドが(指定された次元の 1 つで)サイズ変更可能ではありません。
0 操作に成功しました。

すべての関数プロトタイプがファイル natuser.h で宣言されます。

Top of page