インテル® Fortran コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス
このトピックは、Windows* にのみ適用されます。
標準の Fortran はオブジェクトをサポートしませんが、標準の Fortran モジュールを提供しています。モジュールとはグローバルな名前でグループ化された宣言のセットのことで、USE 文によってほかのプログラムユニットから使用することができます。
インテル® Fortran モジュールウィザードは、1 つまたは複数のモジュールを含むソースファイルを生成します。モジュールに格納される情報の形式には次のものがあります。
派生型定義: タイプ情報に含まれているデータ構造の定義
定数定義: タイプ情報に含まれている識別子と列挙子をインクルードした Fortran PARAMETER 宣言
プロシージャー・インターフェイス定義: タイプ情報に含まれているプロシージャーを記述する Fortran インターフェイス・ブロック
プロシージャー定義: タイプ情報に含まれているプロシージャーのジャケットルーチン (jacket routines) 機能を持つ Fortran 関数とサブルーチン
ジャケットルーチン (jacket routines) は、データ変換と低レベル呼び出しの詳細を処理することで、Fortran から外部プロシージャーを簡単に呼び出せるようにするルーチンです。
インテル® Fortran モジュールウィザードはモジュールを使用することで、オブジェクトや DLL によって公開されているデータ構造とプロシージャーを 1 つの場所にカプセル化することができます。その後、プログラマーはこれらの定義を複数の Fortran プログラムで共有することができます。
プログラムには、適切な USE 文に加えて、関数呼び出しやサブルーチン呼び出しを追加する必要があります。
インテル® Fortran モジュールウィザードによって生成されるルーチンは、Fortran から呼び出されることを念頭に置いて設計されています。これらのルーチンは、(Fortran から呼び出されることを念頭に置いて設計されていない) 適切なシステムルーチンを呼び出して、COM およびオートメーション・オブジェクトを使用するために必要なコーディングを単純化します。
インテル® Visual Fortran は、Fortran プログラマーに、COM およびオートメーション機能の高水準な抽象化を提示するランタイムルーチンのセットを提供します。Fortran モジュールウィザードが生成する Fortran インターフェイスでは、オートメーション・オブジェクトと COM オブジェクトの違いはありません。
指定したオプションに応じて、生成されたコードには次のルーチンが含まれます。
IFCOM ルーチン (COMxxxxx) |
|
---|---|
オブジェクトのインターフェイスに参照を追加します。 |
|
プログラマティック識別子を渡し、対応するクラス識別子を返します。 |
|
クラス識別子文字列を渡し、対応するクラス識別子を返します。 |
|
COMCreateObjectByProgID または COMCreateObjectByGUID を実行する汎用ルーチン。 |
|
クラス識別子を渡し、オブジェクトのインスタンスを作成します。オブジェクトのインターフェイスへのポインターを返します。 |
|
プログラマティック識別子を渡し、オブジェクトのインスタンスを作成します。オブジェクトの IDispatch インターフェイスへのポインターを返します。 |
|
クラス識別子を渡し、現在アクティブなオブジェクトのインターフェイスへのポインターを返します。 |
|
プログラマティック識別子を渡し、現在アクティブなオブジェクトの IDispatch インターフェイスへのポインターを返します。 |
|
COM ライブラリーを初期化します。ほかの COM または AUTO ルーチンを呼び出す前に、ライブラリーを初期化する必要があります。 |
|
2 つの GUID が同じかどうかを決定します。 |
|
ファイル名を渡し、ファイルを操作できるオートメーション・オブジェクトの IDispatch インターフェイスへのポインターを返します。 |
|
インターフェイス識別子を渡し、オブジェクトのインターフェイスへのポインターを返します。 |
|
プログラムがオブジェクトのインターフェイスへの参照で終了したことを示します。 |
|
GUID を渡し、対応する文字列表現を返します。 |
|
COM ライブラリーの初期化を解除します。これは、最後に呼び出す COM ルーチンでなければなりません。 |
IFAUTO オートメーション・ルーチン (AUTOxxxxx) |
|
---|---|
引数名と値を渡し、引数リストデータ構造に引数を追加します。 |
|
AUTOInvoke に渡すことになる引数を保持する引数リストデータ構造を割り当てます。 |
|
引数リストデータ構造の割り当てを解除します。 |
|
メソッドが例外ステータスを返したときに、例外情報を取得します。 |
|
プロパティーの名前または識別子を渡し、オートメーション・オブジェクトのプロパティー値を取得します。 |
|
プロパティーのメンバー ID を渡し、引数リストの第 1 引数にオートメーション・オブジェクトのプロパティー値を取得します。 |
|
引数リストデータ構造を渡し、引数リストの第 1 引数に指定されたオートメーション・オブジェクトのプロパティーの値を取得します。 |
|
オブジェクトのメソッドの名前または識別子と、引数リストデータ構造を渡します。渡された引数を使用してメソッドを呼び出します。 |
|
プロパティーの名前または識別子と値を渡します。オートメーション・オブジェクトのプロパティー値を設定します。 |
|
プロパティーのメンバー ID を渡し、引数リストの第 1 引数を使用してオートメーション・オブジェクトのプロパティーの値を設定します。 |
|
引数リストデータ構造を渡し、引数リストの第 1 引数で指定されたオートメーション・オブジェクトのプロパティーの値を設定します。 |
次のコードは、インテル® Fortran モジュールウィザードが生成したコードの一部で、アノテーションが付けられています。このコードは、IGeneric ドキュメント・インターフェイスの Save メソッドの COM タイプ情報から生成されます。
INTERFACE
! ドキュメントをディスクに保存する 1
INTEGER*4 FUNCTION IGenericDocument_Save($OBJECT, vFilename, &
vBoolPrompt, pSaved) 2
USE IFWINTY
INTEGER (INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! オブジェクト・ポインター
!DIR$ ATTRIBUTES VALUE :: $OBJECT 3
TYPE (VARIANT), INTENT(IN), OPTIONAL :: vFilename ! (オプション引数) 4
!DIR$ ATTRIBUTES REFERENCE :: vFilename
TYPE (VARIANT), INTENT(IN), OPTIONAL :: vBoolPrompt ! (オプション引数)
!DIR$ ATTRIBUTES REFERENCE :: vBoolPrompt
INTEGER, INTENT(OUT) :: pSaved ! DsSaveStatus 5
!DIR$ ATTRIBUTES REFERENCE :: pSaved
!DIR$ ATTRIBUTES STDCALL :: IGenericDocument_Save
END FUNCTION IGenericDocument_Save
END INTERFACE
POINTER(IGenericDocument_Save_PTR, IGenericDocument_Save) ! ルーチンポインター 6
この例の注意事項:
1 タイプ情報がメンバー関数を記述するコメントを提供する場合、そのコメントはプロシージャーが始まる前に置かれます。
2 プロシージャーへの第 1 引数は常に $OBJECT です。これはオブジェクトのインターフェイスへのポインターです。残りの引数名はタイプ情報から決定されます。オブジェクトのインターフェイスへのポインターの取得方法については、「オブジェクト・インターフェイスへのポインターの取得」を参照してください。
3 これは、引数の呼び出し規約を指定するために使用される ATTRIBUTES ディレクティブ文の例です。
4 VARIANT は、任意の形式のオートメーション・データを格納できるデータ構造です。ここには、データ形式を識別するフィールドと、データ値を保持する共用体が含まれています。VARIANT 引数を使用することで、呼び出し側は、メンバー関数で予期されるデータ型への変換が可能な任意のデータ型を使用することができます。
5 ほぼすべての COM メンバー関数は、HRESULT 型のステータスを返します。このため、COM メンバー関数が出力を生成するときには、出力引数を使用して値を返します。この例では、"pSaved" 引数はルーチン特有のステータス値を返します。
6 COM メンバー関数のインターフェイスは、ダイナミック・リンク・ライブラリー関数のインターフェイスとよく似ていますが、大きな違いが 1 つあります。DLL 関数とは異なり、COM メンバー関数のアドレスは、プログラムのリンク時には不明です。このため、オブジェクトのインターフェイスへのポインターをランタイム時に取得し、これをもとにメンバー関数のアドレスを計算する必要があります。
次のコードは、インテル® Fortran モジュールウィザードが "Save" 関数用に生成したコードのラッパーで、アノテーションが付けられています。ラッパーの名前は、対応するメンバー関数の名前の前に "$" 文字を付けたものです。
! ドキュメントをディスクに保存する
INTEGER*4 FUNCTION $IGenericDocument_Save($OBJECT, vFilename, & 1
vBoolPrompt, pSaved)
IMPLICIT NONE
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! オブジェクト・ポインター
!DIR$ ATTRIBUTES VALUE :: $OBJECT
TYPE (VARIANT), INTENT(IN), OPTIONAL :: vFilename
!DIR$ ATTRIBUTES REFERENCE :: vFilename
TYPE (VARIANT), INTENT(IN), OPTIONAL :: vBoolPrompt
!DIR$ ATTRIBUTES REFERENCE :: vBoolPrompt
INTEGER, INTENT(OUT) :: pSaved ! DsSaveStatus
!DIR$ ATTRIBUTES REFERENCE :: pSaved
INTEGER(4) $RETURN
INTEGER(INT_PTR_KIND()) $VTBL ! インターフェイス関数テーブル 2
POINTER($VPTR, $VTBL)
TYPE (VARIANT) :: $VAR_vFilename
TYPE (VARIANT) :: $VAR_vBoolPrompt
IF (PRESENT(vFilename)) THEN 3
$VAR_vFilename = vFilename
ELSE
$VAR_vFilename = OPTIONAL_VARIANT
END IF
IF (PRESENT(vBoolPrompt)) THEN
$VAR_vBoolPrompt = vBoolPrompt
ELSE
$VAR_vBoolPrompt = OPTIONAL_VARIANT
END IF
$VPTR = $OBJECT ! インターフェイス関数テーブル 4
$VPTR = $VTBL + 84 ! ルーチンテーブルのオフセットを足す
IGenericDocument_Save_PTR = $VTBL
$RETURN = IGenericDocument_Save($OBJECT, $VAR_vFilename, &
$VAR_vBoolPrompt, pSaved)
$IGenericDocument_Save = $RETURN
END FUNCTION $IGenericDocument_Save
この例の注意事項:
1 ラッパーは、メンバー関数のインターフェイスと同じ引数名を使用します。
2 ラッパーは、インターフェイス・ポインターと、インターフェイスのタイプ情報に含まれるオフセットから、メンバー関数のアドレスを計算します。実装用語としてのインターフェイス・ポインターとは、"Interface Function Table" と呼ばれる関数ポインターの配列へのポインターを参照するポインターのことです。
3 COM またはオートメーション・ルーチンの引数は省略可能です。ラッパーは呼び出しの細部を処理し、呼び出しに含まれていない省略可能な引数を自動的に指定します。
4 "Save" メンバー関数のオフセットは 84 です。コードは、前のインターフェイスで宣言した関数ポインター IGenericDocument_Save_PTR に計算されたアドレスを代入した後、関数を呼び出します。
次のコードは、IApplication インターフェイスの Rebuild All メソッドのオートメーション・タイプ情報からインテル® Fortran モジュールウィザードが生成したコードの一部で、アノテーションが付けられています。
! 指定された構成ですべてのファイルをリビルドする
SUBROUTINE IApplication_RebuildAll($OBJECT, Configuration, $STATUS) 1
IMPLICIT NONE
INTEGER(INT_PTR_KIND()), INTENT(IN) :: $OBJECT ! オブジェクト・ポインター
!DIR$ ATTRIBUTES VALUE :: $OBJECT
TYPE (VARIANT), INTENT(IN), OPTIONAL :: Configuration
!DIR$ ATTRIBUTES REFERENCE :: Configuration
INTEGER(4), INTENT(OUT), OPTIONAL :: $STATUS ! メソッドのステータス
!DIR$ ATTRIBUTES REFERENCE :: $STATUS
INTEGER(4) $$STATUS
INTEGER (INT_PTR_KIND) invokeargs
invokeargs = AUTOALLOCATEINVOKEARGS() 2
IF (PRESENT(Configuration)) CALL AUTOADDARG(invokeargs, '$ARG1', &
Configuration, AUTO_ARG_IN)
$$STATUS = AUTOINVOKE($OBJECT, 28, invokeargs) 3
IF (PRESENT($STATUS)) $STATUS = $$STATUS 4
CALL AUTODEALLOCATEINVOKEARGS (invokeargs) 5
END SUBROUTINE IApplication_RebuildAll
この例の注意事項:
1 プロシージャーへの第 1 引数は常に $OBJECT です。これは、オートメーション・オブジェクトの IDispatch インターフェイスへのポインターです。プロシージャーへの最後の引数は常に $STATUS です。これは、メソッドのリターンステータスを確認するときに指定できる省略可能な引数です。IDispatch Invoke メンバー関数は HRESULT 型のステータスを返します。HRESULT は 32 ビット値で、Windows* のエラーコードと同じ構造を持ちます。$OBJECT 引数と $STATUS 引数の間には、タイプ情報から決定されたメソッド引数の名前が含まれています。タイプ情報には引数の名前が含まれていないこともあります。この場合、Fortran モジュールウィザードは "$ARGn" という名前を作成します。
2 AUTOAllocateInvokeArgs は、ユーザーがメソッドに渡す引数を収集するために使用されるデータ構造を割り当てます。AUTOAddArg は、このデータ構造に引数を 1 つ追加します。
3 AUTOInvoke は、引数リストを渡して、指定されたメソッドを呼び出します。これによりステータス結果が返されます。
4 呼び出し側がステータス引数 (STATUS) を指定した場合、コードはそこにステータス結果をコピーします。
5AUTODeallocateInvokeArgs は、引数リストデータ構造が使用するメモリーの割り当てを解除します。