[COBOLのはじめ方] Part16: CALL文による外部プログラムの呼び出し

COBOLプログラミングのステップアップへようこそ!今回は、プログラムを部品化し、効率的に開発を進めるための重要な機能「CALL文」について学びます。CALL文を使うことで、別のCOBOLプログラム(サブルーチンや外部プログラムと呼ばれる)を呼び出すことができます。これにより、コードの再利用性が高まり、プログラム全体の保守性も向上します。

大きなプログラムを機能ごとに小さなプログラムに分割し、それらをCALL文で連携させることで、見通しの良い、管理しやすいシステムを構築できます。さっそくCALL文の基本的な使い方から見ていきましょう!

1. CALL文の基本的な構文

CALL文は、指定したプログラムを呼び出すための命令です。最もシンプルな形式は以下のようになります。


CALL 'プログラム名'.
       

ここで、'プログラム名' には呼び出したい外部プログラムのPROGRAM-IDを指定します。プログラム名は、リテラル(シングルクォーテーションまたはダブルクォーテーションで囲む)で直接指定するか、プログラム名を格納したデータ項目(識別子)で指定することができます。

ポイント: プログラム名は通常、大文字で記述され、システムによっては命名規則(例:8文字以内)があることに注意してください。

簡単な例:パラメータなしの呼び出し

まずは、パラメータ(データの受け渡し)なしで、単純に別のプログラムを呼び出す例を見てみましょう。

呼び出し元プログラム (MAINPROG.cbl)


IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
    DISPLAY 'メインプログラムを開始します。'.
    CALL 'SUBPROG'.
    DISPLAY 'メインプログラムを終了します。'.
    STOP RUN.
       

呼び出し先プログラム (SUBPROG.cbl)


IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
PROCEDURE DIVISION.
    DISPLAY '*** サブプログラムが呼び出されました ***'.
    GOBACK. *> または EXIT PROGRAM.
       

この例では、MAINPROG が実行されると、途中で CALL 'SUBPROG'. により SUBPROG が呼び出され、サブプログラム内の処理(ここではメッセージ表示)が実行されます。サブプログラムの処理が終わると、呼び出し元の次の命令(DISPLAY 'メインプログラムを終了します。')に戻ります。

注意点: サブプログラムの最後は、STOP RUN ではなく GOBACK または EXIT PROGRAM を使って呼び出し元プログラムに制御を戻します。

2. USING句によるパラメータの受け渡し

多くの場合、呼び出し元プログラムから呼び出し先プログラムへデータを渡したり、逆に処理結果を受け取ったりする必要があります。このようなデータの受け渡しには、CALL文のUSING句を使用します。


CALL 'プログラム名' USING データ項目1 データ項目2 ... .
       

呼び出し先のプログラムでは、受け取るデータをLINKAGE SECTIONで定義します。LINKAGE SECTIONは、DATA DIVISION内に記述し、外部プログラムから渡されるデータ項目を定義するための特別な領域です。

パラメータ受け渡しの例

呼び出し元プログラム (MAINPROG2.cbl)


IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG2.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-SEND-DATA   PIC X(10) VALUE 'HELLO'.
01 WS-RECEIVE-DATA PIC 9(5).
PROCEDURE DIVISION.
    DISPLAY 'メインプログラム: 送信データ = ' WS-SEND-DATA.
    CALL 'SUBPROG2' USING WS-SEND-DATA WS-RECEIVE-DATA.
    DISPLAY 'メインプログラム: 受信データ = ' WS-RECEIVE-DATA.
    STOP RUN.
       

呼び出し先プログラム (SUBPROG2.cbl)


IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG2.
DATA DIVISION.
LINKAGE SECTION. *> パラメータを受け取るためのセクション
01 LS-PARAM1      PIC X(10).
01 LS-PARAM2      PIC 9(5).
PROCEDURE DIVISION USING LS-PARAM1 LS-PARAM2. *> USING句で受け取る
    DISPLAY 'サブプログラム: 受け取ったデータ1 = ' LS-PARAM1.
    MOVE 12345 TO LS-PARAM2. *> 受け取ったデータ項目を変更
    DISPLAY 'サブプログラム: 設定したデータ2 = ' LS-PARAM2.
    GOBACK.
       

この例では、MAINPROG2WS-SEND-DATAWS-RECEIVE-DATASUBPROG2に渡しています。SUBPROG2は、LINKAGE SECTIONで定義されたLS-PARAM1LS-PARAM2でこれらを受け取ります。PROCEDURE DIVISIONの見出しにもUSING句を記述し、受け取るパラメータを指定します。

重要なのは、CALL文のUSING句のデータ項目と、呼び出される側のPROCEDURE DIVISION USING句およびLINKAGE SECTIONのデータ項目の数、順序、型、長さが一致している必要があるということです。

パラメータの渡し方:BY REFERENCE と BY CONTENT

USING句では、パラメータの渡し方を指定できます。

指定 意味 説明
(指定なし) または BY REFERENCE 参照渡し データ項目のアドレスが渡されます。サブプログラム側で値を変更すると、呼び出し元のデータ項目の値も変更されます。これがCOBOLのデフォルトであり、最も一般的に使われます。上の例も参照渡しです。
BY CONTENT 内容渡し データ項目の値のコピーが渡されます。サブプログラム側で値を変更しても、呼び出し元のデータ項目の値は変更されません

特定のパラメータだけ渡し方を指定することも可能です。


*> WS-DATA1は参照渡し、WS-DATA2は内容渡し
CALL 'SUBPROG3' USING BY REFERENCE WS-DATA1
                       BY CONTENT WS-DATA2.

*> このように記述することも可能(デフォルトがBY REFERENCEのため)
CALL 'SUBPROG3' USING WS-DATA1
                       BY CONTENT WS-DATA2.
       
ポイント: BY VALUE という値渡しもありますが、これは主にC言語など他の言語との連携で使われることが多く、処理系によってはサポート状況が異なります。COBOLプログラム同士の連携では、BY REFERENCEBY CONTENT を理解しておけば十分でしょう。

3. コンパイルと実行

CALL文を使用する場合、呼び出し元と呼び出し先のプログラムをそれぞれコンパイルする必要があります。そして、実行時にはこれらのプログラムが結合(リンク)される必要があります。

ここでは、オープンソースの GnuCOBOL を使った場合の例を示します(環境によってコマンドは異なります)。

GnuCOBOLでのコンパイル例 (動的呼び出し)

  1. サブプログラムのコンパイル (モジュールとして):
    サブプログラムを共有ライブラリ(またはDLL)としてコンパイルします。-m オプションを使用します。
    
    cobc -m SUBPROG2.cbl
                
    これにより、SUBPROG2.so (Linux/macOS) や SUBPROG2.dll (Windows) のようなファイルが生成されます。
  2. メインプログラムのコンパイルと実行:
    メインプログラムを通常通りコンパイルし、実行します。
    
    cobc -x MAINPROG2.cbl
    ./MAINPROG2
                
    実行時に、OSが動的にサブプログラム(SUBPROG2.soSUBPROG2.dll)をロードして結合します。サブプログラムのライブラリが適切な場所(カレントディレクトリや環境変数で指定されたパス)にある必要があります。

GnuCOBOLでのコンパイル例 (静的リンク)

  1. サブプログラムのコンパイル (オブジェクトファイルとして):
    -c オプションでオブジェクトファイル (.o) を作成します。
    
    cobc -c SUBPROG2.cbl
                
    これにより SUBPROG2.o が生成されます。
  2. メインプログラムのコンパイルとリンク:
    メインプログラムのコンパイル時に、サブプログラムのオブジェクトファイルも一緒に指定してリンクします。
    
    cobc -x MAINPROG2.cbl SUBPROG2.o
    ./MAINPROG2
                
    これにより、実行ファイル MAINPROG2 にサブプログラムが組み込まれます。
注意点: コンパイル方法は環境やCOBOL処理系(Fujitsu COBOL, Micro Focus COBOLなど)によって異なります。使用している環境のマニュアルを確認してください。

4. まとめと次のステップ

今回は、CALL文を使った外部プログラムの呼び出し、USING句とLINKAGE SECTIONを使ったパラメータの受け渡しについて学びました。CALL文は、プログラムのモジュール化、再利用性向上、保守性向上のために非常に重要な機能です。

  • CALL文で他のプログラムを呼び出せる。
  • USING句でデータを渡せる。
  • 呼び出し先はLINKAGE SECTIONPROCEDURE DIVISION USINGでデータを受け取る。
  • BY REFERENCE(参照渡し)とBY CONTENT(内容渡し)がある。
  • 呼び出し元と呼び出し先は別々にコンパイルし、実行時に結合する必要がある。

次のステップでは、CALL文と密接に関連する「LINKAGE SECTIONとパラメータ受け渡し」についてさらに詳しく掘り下げ、そして、共通のコード部品を複数のプログラムで利用するための「COPY文とコードの再利用」について学んでいきます。お楽しみに!

参考情報

より詳しい情報や他のCOBOL処理系での使い方については、以下のドキュメントや解説記事を参照してください。

  • GnuCOBOL Programmer’s Guide: (GnuCOBOLの公式ドキュメント。CALL文に関する詳細な説明が含まれています)
    ※ Web検索などで “GnuCOBOL Programmer’s Guide” を探してください。直接リンクは規約上記載できませんが、公式情報が最も信頼できます。
  • COBOL入門 (さまざまなWebサイト):
    多くの技術解説サイトでCOBOLのCALL文について解説されています。「COBOL CALL文 使い方」などで検索してみてください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です