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

CALL

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

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

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

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

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


機能

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

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

TP モニタが CALL インターフェイスをサポートしている場合は、TP モニタの制御下で実行されるプログラム内で 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 個まで指定できます。ただし、INTERFACE4 オプションを使用している場合は、指定できる数が変わります。 この場合、パラメータの数は、カタログ化オブジェクトのサイズによって制限されます。 Natural オブジェクトにある他のすべてのステートメントによって影響を受けますが、最大 16370 個までのパラメータを使用できます。 標準のリンケージ登録規則を使用します。 指定する各パラメータフィールドごとに、1 つのアドレスがパラメータリストで渡されます。

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

注意:
パック 10 進数の正記号の内部表現は、制御が外部プログラムに渡される前にNTCMPO マクロ(コンパイルオプション)の PSIGNF パラメータで指定した値に変更されます。

Top of page

リターンコード

呼び出されたプログラムのコンディションコード(Natural に戻ったときのレジスタ 15 の内容)は、Natural システム関数 RET(リターンコード関数)で取得できます。

例:

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

Top of page

レジスタの使用方法

レジスタ 内容
R1 パラメータアドレスリストへのアドレスポインタ。
R2 フィールド定義リストへのアドレスポインタ。 フィールド定義リストには、パラメータリストで渡される最初の 128 個のフィールドに関する情報が含まれます。 各定義は、次の情報を含む 4 バイトのエントリです。
  • 1 バイト目には、変数のタイプ(A、B、...)が格納されます。

  • タイプ A の変数のサイズが 32767 バイトを超えた場合、変数はタイプ Y として渡されます。

  • タイプ B の変数のサイズが 32767 バイトを超えた場合、変数はタイプ X として渡されます。タイプ X と Y は、標準 CALL インターフェイスでロング英数字およびバイナリ変数をサポートするために導入されました。

フィールドタイプが N または P の場合:

  • 2 バイト目には、全体の桁数が格納されます。

  • 3 バイト目には、小数点以上の桁数が格納されます。

  • 4 バイト目には、小数点以上の桁数が格納されます。

フィールドタイプが X または Y の場合:

  • 2 バイト目は未使用。

  • 3~4 バイト目には、ゼロが格納されます。

  • フィールドの長さは R4 を介して渡されます。

その他のフィールドタイプの場合:

  • 2 バイト目は未使用。

  • 3~4 バイト目には、フィールドの長さが格納されます。

R3 フィールド長のリストへのアドレスポインタ。 各長さフィールドは 4 バイトのエントリで、パラメータリストで渡される各フィールドの長さが含まれます。 配列の場合、長さは、個々のオカレンスが持つ長さの合計になります。
R4

タイプ X および Y 専用:

  • サイズが 32767 バイトを超えたタイプ A または B の各変数に対応する、長さが 4 バイトのエントリ。

R13 18 ワードのセーブエリアのアドレス。
R14 リターンアドレス。
R15 エントリアドレスまたはリターンコード。

Top of page

境界の配置

すべてのユーザー定義変数が保存される Natural データエリアは、常にダブルワード境界から始まります。

DEFINE DATA を使用している場合、すべてのデータブロック(例えば、LOCALGLOBAL ブロック)はダブルワードで配置され、すべての構造(レベル 1)のフルワードで配置されます。

データエリア内での配置はユーザーの責任で行われ、変数が Natural に定義された順番によって決まります。

Top of page

Adabas コール

呼び出される側のプログラムには、Adabas へのコールが含まれていることがあります。 呼び出される側のプログラムでは、Adabas オープンまたはクローズコマンドは発行できません。 Adabas によって、参照されるデータベースフィールドがすべて開かれます。

Adabas 排他(EXU)更新モードを使用する場合は、参照されるすべてのファイル開くために、Natural プロファイルパラメータ OPRB(データベースのオープンとクローズ処理)を使用する必要があります。 EXU 更新モードを使用する前に、Natural 管理者に相談してください。

呼び出されたプログラムによってトランザクションを開始または終了する Adabas コマンドが発行された場合、Natural 側ではトランザクションステータスの変化を認識できません。

Adabas へのコールは、それぞれの TP モニタまたはオペレーティングシステム用の Adabas アプリケーションプログラミングインターフェイス(API)の呼び出し規則に適合している必要があります。 これは、Natural がサーバーとして動作している場合にも適用されます(例:z/OS または SMARTS の環境下)。

Top of page

ダイレクトロードとダイナミックロード

呼び出されたプログラムは Natural ニュークリアスに直接リンクされるか、またはプログラムが最初に呼び出されたときにダイナミックにロードされます。ニュークリアスに直接リンクされる場合、プログラムは、『オペレーション』ドキュメントの「Natural パラメータモジュール」に記載されているプロファイルパラメータ CSTATIC(Natural にスタティックにリンクされるプログラム)で指定されます。

プログラムがダイナミックにロードされる場合は、呼び出されるプログラムを含むロードモジュールライブラリを、Natural 実行 JCL または適切な TP モニタプログラムライブラリにある Natural ロードライブラリに連結する必要があります。 詳細については、Natural 管理者に確認してください。

例:

次の例は、国番号を対応する国名に変換する目的で COBOL プログラム TABSUB を呼び出す Natural プログラムを示しています。 2 つのパラメータフィールドが、Natural プログラムによって TABSUB に渡されます。

呼び出す側の Natural プログラム:

** Example 'CALEX1': CALL PROGRAM 'TABSUB'                              
************************************************************************
DEFINE DATA LOCAL                                                       
1 EMPLOY-VIEW VIEW OF EMPLOYEES                                         
  2 NAME                                                                
  2 BIRTH                                                               
  2 COUNTRY                                                             
*                                                                       
1 #COUNTRY      (A3)                                                    
1 #COUNTRY-NAME (A15)                                                   
1 #FIND-FROM    (D)                                                     
1 #FIND-TO      (D)                                                     
END-DEFINE                                                              
*                                                                       
MOVE EDITED '19550701' TO #FIND-FROM (EM=YYYYMMDD)                      
MOVE EDITED '19550731' TO #FIND-TO   (EM=YYYYMMDD)                      
*                                                                       
FIND EMPLOY-VIEW WITH BIRTH = #FIND-FROM THRU #FIND-TO                  
  MOVE COUNTRY TO #COUNTRY                                              
  /*                                              
  CALL 'TABSUB' #COUNTRY #COUNTRY-NAME            
  /*                                              
  DISPLAY NAME BIRTH (EM=YYYY-MM-DD) #COUNTRY-NAME
END-FIND                                          
END                                              

呼び出される側の COBOL プログラム TABSUB:

IDENTIFICATION DIVISION. 
PROGRAM-ID. TABSUB. 
REMARKS. THIS PROGRAM PROVIDES THE COUNTRY NAME 
        FOR A GIVEN COUNTRY CODE. 
ENVIRONMENT DIVISION. 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
LINKAGE SECTION. 
01 COUNTRY-CODE  PIC X(3). 
01 COUNTRY-NAME  PIC X(15). 
PROCEDURE DIVISION USING COUNTRY-CODE COUNTRY-NAME. 
P-CONVERT. 
   MOVE SPACES TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'BLG' MOVE 'BELGIUM' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'DEN' MOVE 'DENMARK' TO COUNTRY-NAME.  
   IF COUNTRY-CODE = 'FRA' MOVE 'FRANCE' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'GER' MOVE 'GERMANY' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'HOL' MOVE 'HOLLAND' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'ITA' MOVE 'ITALY' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'SPA' MOVE 'SPAIN' TO COUNTRY-NAME. 
   IF COUNTRY-CODE = 'UK'  MOVE 'UNITED KINGDOM' TO COUNTRY-NAME. 
P-RETURN. 
GOBACK.

Top of page

リンケージの規則

標準のリンケージ登録表記は、バッチモードで使用されます。 各 TP モニタには、独自の規則があります。 これらの規則には従う必要があり、従わなかった場合には予期できない結果が生じることがあります。

次のセクションでは、サポートされている TP モニタに適用される規則について説明します。

Com-plete を使用した CALL

呼び出される側のプログラムは、Com-plete オンラインロードライブラリ内に存在している必要があります。 これにより、Com-plete でプログラムをダイナミックにロードすることが可能になります。 Com-plete ユーティリティ ULIB を使用すると、プログラムをカタログすることができます。

CICS を使用した CALL

呼び出される側のプログラムは、CICS ライブラリに連結されたロードモジュールライブラリまたは DFHRPL ライブラリのいずれかに存在している必要があります。 また、CICS がプログラムを特定してロードできるように、プログラムは動作しているPPT の PPT エントリを保持する必要があります。

リンケージ規則では、パラメータリストアドレスとそれに続くフィールド定義リストアドレスを TWA と COMMAREA の先頭にあるフルワードで渡します。

NCIPARM パラメータモジュール内にあるパラメータ FLDLEN では、フィールド長リストも渡すかどうかを制御します(デフォルトでは、渡しません)。 COMMAREA の長さ(0、8、12、または16)は、渡されるリストアドレスの数(0、2、3、または 4)を反映しています。 最後のアドレスリストは、セットされている上位ビットによって示されます。 ユーザーは、TWA または COMMAREA のそれぞれについて、アドレス可能であることを保証する必要があります。 これは、ユーザープログラムが Natural に対してスタティックまたはダイレクトリンクプログラムとして定義されていない場合にのみ必要になります。その場合、パラメータリストへのポインタはレジスタ 1 を介して渡され、さらに定義リストへのポインタはレジスタ 2 を介して、フィールド長リストへのポインタはレジスタ 3 を介して、ラージフィールド長リストはレジスタ 4 を介して渡されます。

NCIPARM パラメータモジュール内にあるパラメータ FLDLEN および COMACAL では、COMMAREA の内容を制御します。

パラメータ値のアドレスリストのアドレスではなく、パラメータ値自体を COMMAREA で渡す必要がある場合は、コールの前に Natural(コールオプション)端末コマンド %P=C を発行します。

通常、Natural プログラムから Natural 以外のプログラムを呼び出すと、呼び出されたプログラムは会話型の端末 I/O を発行し、Natural スレッドはユーザーがデータを入力するまでブロックされます。 Natural スレッドがブロックされるのを防ぐには、端末コマンド %P=V を使用できます。

通常、Natural プログラムで CICS 環境下の Natural 以外のプログラムを呼び出す場合、コールは EXEC CICS LINK 要求によって実行されます。 コールに標準リンクを使用する場合は、端末コマンド %P=S を発行します。 (この場合、呼び出されたされたプログラムでは、標準的な方法でレジスタを使用することで、標準のリンケージ規則に従う必要があります)。

31 ビットモード環境では、次の処理が適用されます。AMODE=24 にリンクされたプログラムを呼び出し、またスレッドが 16 MB よりも上にある場合は、"値によるコール"が自動的に実行されます。つまり、呼び出されたプログラムに渡すように指定されたパラメータは、16 MB境界よりも下にコピーされます。

CICS 環境下でのリターンコード

CICS 自体はCICS の規則に従ったコール(EXEC CICS LINK)の戻り値はサポートしていませんが、C/C++ プログラムのコールでは、例外として、exit() 関数または return() ステートメントが渡す値は EIBRESP2 フィールドに保存されます。 ただし、Natural CICS インターフェイスでは CALL ステートメントのリターンコードがサポートされているため、呼び出されたプログラムから制御が戻ると、Natural によって最初に EIBRESP2 フィールドにゼロ以外のリターンコードがあるかどうかがチェックされます。 次に、COMMAREA の最初のフルワードが変更されたかどうかがチェックされます。 変更されている場合は、その新しい内容がリターンコードになります。 変更されていない場合は、TWA がチェックされ、その新しい内容がリターンコードになります。 2 つのフルワードがいずれも変更されていない場合、リターンコードは 0 になります。

注意:
パラーメータ値を COMMAREA で渡した場合(%P=C)、EIBRESP2 フィールドのリターンコードだけがチェックされます。つまり、C/C++ 以外のプログラムでは、リターンコードは常に 0 になります。

CICS の使用例:

IDENTIFICATION DIVISION. 
PROGRAM-ID. TABSUB. 
REMARKS. THIS PROGRAM PERFORMS A TABLE LOOK-UP AND 
         RETURNS A TEXT MESSAGE. 
ENVIRONMENT DIVISION. 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
01 MSG-TABLE. 
   03  FILLER       PIC X(15) VALUE 'MESSAGE1       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE2       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE3       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE4       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE5       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE6       '.  
   03  FILLER       PIC X(15) VALUE 'MESSAGE7       '.  
01 TAB REDEFINES MSG-TABLE.  
   03  MESSAGE OCCURS 7 TIMES PIC X(15).    
LINKAGE SECTION.   
01 TWA-DATA. 
   03 PARM-POINTER USAGE IS POINTER. 
01 PARM-LIST.                        
   03 DATA-LOC-IN  USAGE IS POINTER. 
   03 DATA-LOC-OUT USAGE IS POINTER. 
01 INPUT-DATA.                       
   03  INPUT-NUMBER      PIC 99.     
01 OUTPUT-DATA.                      
   03  OUTPUT-MESSAGE    PIC X(15).  
PROCEDURE DIVISION.                  
100-INIT.                            
    EXEC CICS ADDRESS TWA(ADDRESS OF TWA-DATA) END-EXEC. 
    SET ADDRESS OF PARM-LIST   TO PARM-POINTER.          
    SET ADDRESS OF INPUT-DATA  TO DATA-LOCIN.            
    SET ADDRESS OF OUTPUT-DATA TO DATA-LOC-OUT.          
200-PROCESS.                                        
    MOVE MESSAGE (INPUT-NUMBER) TO OUTPUT-MESSAGE.  
300-RETURN.                                         
    EXEC CICS RETURN END-EXEC.                      
400-DUMMY.                                          
    GO-BACK.

Top of page

PL/I プログラムのコール

PL/I で書かれた呼び出される側のプログラムでは、次の追加手順が必要です。

パラメータフィールドを定義するための推奨される手法について、次の例で説明します。

PLIPROG: PROC(INPUT_PARM_1, INPUT_PARM_2) OPTIONS(MAIN); 
      DECLARE (INPUT_PARM_1, INPUT_PARM_2) FIXED;        
      PTR_PARM_1 = ADDR(INPUT_PARM_1);                   
      PTR_PARM_2 = ADDR(INPUT_PARM_2);                   
      DECLARE FIRST_PARM        PIC '99'   BASED (PTR_PARM_1); 
      DECLARE SECOND_PARM       CHAR(12)   BASED (PTR_PARM_2);

入力リストの各パラメータは、一意な要素として扱われる必要があります。 入力パラメータの数は、Natural プログラムから渡される数と完全に一致している必要があります。 入力パラメータとそれらの属性は、Natural の定義と一致している必要があります。一致していない場合は、予測できない結果が生じることがあります。 PL/I でパラメータを引き渡す方法の詳細については、関連のIBM PL/I ドキュメントを参照してください。

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

PL/I プログラムのコールの例

** Example 'CALEX2': CALL PROGRAM 'NATPLI'                              
************************************************************************
DEFINE DATA LOCAL                                                       
1 EMPLOY-VIEW VIEW OF EMPLOYEES                                         
  2 NAME                                                                
  2 AREA-CODE                                                           
  2 REDEFINE AREA-CODE                                                  
    3 #AC         (N1)                                                  
*                                                                       
1 #INPUT-NUMBER   (N2)                                                  
1 #OUTPUT-COMMENT (A15)                                                 
END-DEFINE                                                              
*                                                                       
READ EMPLOY-VIEW IN LOGICAL SEQUENCE BY NAME                            
                 STARTING FROM 'WAGNER'                                 
  MOVE ' ' TO #OUTPUT-COMMENT                                           
  MOVE #AC TO #INPUT-NUMBER                                             
  /*                                                                    
  CALL 'NATPLI' #INPUT-NUMBER #OUTPUT-COMMENT
  /*    
END-READ
*       
END    

呼び出される側の PL/I プログラム NATPLI:

NATPLI:  PROC(PARM_COUNT, PARM_COMMENT) OPTIONS(MAIN);
    /*                                            */ 
    /* THIS PROGRAM ACCEPTS AN INPUT NUMBER       */ 
    /* AND TRANSLATES IT TO AN OUTPUT CHARACTER   */ 
    /* STRING FOR PLACEMENT ON THE FINAL          */ 
    /* NATURAL REPORT                             */ 
    /*                                            */ 
    /*                                            */ 
   DECLARE PARM_COUNT, PARM_COMMENT  FIXED;          
   DECLARE ADDR BUILTIN;                             
   COUNT_PTR = ADDR(PARM_COUNT);                     
   COMMENT_PTR = ADDR(PARM_COMMENT);                 
   DECLARE  INPUT_NUMBER    PIC '99' BASED (COUNT_PTR); 
   DECLARE  OUTPUT_COMMENT  CHAR(15) BASED (COMMENT_PTR);
   DECLARE COMMENT_TABLE(9) CHAR(15) STATIC INITIAL     
      ('COMMENT1   ',            
       'COMMENT2   ',            
       'COMMENT3   ',            
       'COMMENT4   ',            
       'COMMENT5   ',            
       'COMMENT6   ',            
       'COMMENT7   ',            
       'COMMENT8   ',            
       'COMMENT9   ');           
    OUTPUT_COMMENT = COMMENT_TABLE(INPUT_NUMBER);  
    RETURN; 
END NATPLI;

CICS 環境下で動作している PL/I プログラムのコールの例

** Example 'CALEX3': CALL PROGRAM 'CICSP'                               
************************************************************************
DEFINE DATA LOCAL                                                       
1 #MESSAGE (A10) INIT <' '>                                             
END-DEFINE                                                              
*                                                                       
CALL 'CICSP' #MESSAGE
DISPLAY #MESSAGE                                                        
*                                                                       
END                                                                    

呼び出される側の PL/I プログラム CICSP:

CICSP: PROCEDURE OPTIONS (MAIN REENTRANT); 
       DCL  1        TWA_ADDRESS    BASED(TWA_POINTER); 
            2        LIST_ADDRESS   POINTER; 
       DCL  1 PTR_TO_LIST           BASED(LIST_ADDRESS); 
            2 PARM_01               POINTER; 
       DCL MESSAGE CHAR(10) BASED(PARM_01); 
       EXEC CICS ADDRESS TWA(TWA_POINTER); 
       MESSAGE='SUCCESS'; EXEC CICS RETURN; END CICSP;

Top of page

C プログラムのコール

C プログラムを使用する前に、そのプログラムをコンパイルしてリンクする必要があります。

INTERFACE4 用に書かれた C プログラムは、メインフレームシステムだけでなく、UNIX、OpenVMS、または Windows システムでも使用できます。 一方、標準 CALL インターフェイス用に書かれた C プログラムは、プラットフォームに依存します。

CALL INTERFACE4 によって C プログラムを呼び出す場合、または Natural サブプログラムが C プログラムから呼び出される場合は、NATXCAL4 を実行可能モジュールにリンクする必要があります。 INTERFACE4 コールバック関数の 1 つを使用して、パラメータ定義とパラメータ値を取得します。 コールバック関数については、次で説明します。

関数 ncxr_if4_callnat を使用して、C プログラムから Natural サブプログラムを実行します。

プロトタイプ:

int ncxr_if4_callnat ( char *natpgm, int parmnum, struct parameter_description *descr );

パラメータの説明:

natpgm 呼び出される Natural サブプログラムの名前。
parmnum サブプログラムに渡されるパラメータフィールドの数。
descr struct parameter_description のアドレス。 この構造の詳細については、「Interface4 のオペランド構造」を参照してください。
return 戻り値: 情報:
0 OK

サブプログラムの実行中に Natural エラーが発生した場合、エラーに関する情報が値 natpgm によって *NAT nnnn の形式で返されます。nnnn は Natural エラー番号に対応しています。

-1 無効なパラメータ番号。
-2 内部エラーが発生しました。

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

標準 CALL による C プログラムのコールの例

** Example 'CALEX4': CALL PROGRAM 'ADD'                                 
************************************************************************
DEFINE DATA LOCAL                                                       
1 #OP1  (I4)                                                            
1 #OP2  (I4)                                                            
1 #SUM  (I4)                                                            
END-DEFINE                                                              
*                                                                       
CALL 'ADD' #OP1 #OP2 #SUM
DISPLAY #SUM                                                            
*                                                                       
END                                                                    

呼び出される側の C プログラム ADD:

/*  
**  Example C Program ADD.c
*/ 
NATFCT ADD (int *op1, int *op2, int *sum)  
{  
*sum = *op1 + *op2;    /* add opperands */  
  
return 0;              /* return successfully */  
} /* ADD */

CALL INTERFACE4 による C プログラムのコールの例

** Example 'CALEX5': CALL PROGRAM 'ADD4'                                
************************************************************************
DEFINE DATA LOCAL                                                       
1 #OP1  (I4)                                                            
1 #OP2  (I4)                                                            
1 #SUM  (I4)                                                            
END-DEFINE                                                              
*                                                                       
CALL INTERFACE4 'ADD4' #OP1 #OP2 #SUM
DISPLAY #SUM                                                            
*                                                                       
END                                                                    

呼び出される側の C プログラム ADD4:

NATFCT ADD4 NATARGDEF(numparm, parmhandle, parmdec)    
{   
NATTYP_I4 op1, op2, sum;               /* local integers */   
int i;                                 /* loop counter */   
struct parameter_description desc;   
int rc;                                /* return code access functions */ 
  
/*   
** test number of arguments   
*/   
if (numparm != 3) return 1;    
  
/*   
** test types of arguments   
*/   
for (i = 0; i < (int) numparm; i++)   
{   
       rc = ncxr_get_parm_info( i, parmhandle, &desc );     
      if ( rc ) return rc;      
         
      if ( desc.format != 'I' || desc.length != sizeof(NATTYP_I4) || desc.dimensions != 0 )     
      {
              return 2;          /* invalid parameter */    
      }   
}   
  
/*   
** get arguments   
*/   
rc = ncxr_get_parm( 0, parmhandle, sizeof op1, (void *)&op1 );   
if ( rc ) return rc;    
  
rc = ncxr_get_parm( 1, parmhandle, sizeof op2, (void *)&op2 );   
if ( rc ) return rc;    
  
/*   
** perform the addition   
*/   
sum = op1 + op2;    
  
/*   
** move the result back to operand 3   
*/   
rc = ncxr_put_parm( 2, parmhandle, sizeof sum, (void *)&sum );   
if ( rc ) return rc;    
  
/*   
** all ok, return success to the caller   
*/  
return 0;   
} /* ADD4 */

Top of page

INTERFACE4

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

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

  キーワード INTERFACE4 を使用しない CALL ステートメント キーワード INTERFACE4 を使用する CALL ステートメント
使用可能なパラメータ数 128 16370 個以下
1 つのパラメータの最大データサイズ 制限なし 1 GB
配列情報の取得
ラージオペランドとダイナミックオペランドのサポート 完全な読み取りアクセス、オペランドのサイズを変更しない書き込み
API 経由でのパラメータアクセス ダイレクト API 経由

パラメータの最大数は、生成プログラム(GP)の最大サイズおよびステートメントの最大サイズによって制限されます。 プログラムに CALL ステートメントのみが含まれている場合は、16370 個のパラメータが使用できます。 他のステートメントを使用すると、最大数は減少します。

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

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 ) 

この機能は、各次元のインデックスを指定可能であることを除けば、ncxr_get_parm と同じです。 未使用の次元のインデックスは 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