Fortran 95/90 はオブジェクトをサポートしませんが,Fortran 95/90 モジュールを提供しています。モジュールとは大域的な名前の下にグループ化された宣言の組のことで,USE 文によって他のプログラム単位から使用することができます。
Fortran Module Wizard は 1 つまたは複数のモジュールを含んでいるソース・ファイルを生成します。モジュールに格納される情報の形式には次のものがあります。
構造型定義は,タイプ情報に含まれているデータ構造の Fortran に等価な定義です。
定数定義は,構造情報と含まれている識別子と列挙型を含む Fortran PARAMETER 宣言です。
手続インタフェース定義は,タイプ情報に含まれている手続を記述する Fortran インタフェース宣言です。
手続定義は,タイプ情報に含まれている手続のジャケット・ルーチンである Fortran 関数とサブルーチンです。
ジャケット・ルーチンは,データ変換と低水準呼び出しの詳細を処理することで,Fortran から外部手続を簡単に呼び出せるようにするルーチンです。
Fortran Module Wizard はモジュールを使用することで,オブジェクトや DLL によって公開されているデータ構造と手続を 1 つの場所にカプセル化することができます。その後,プログラマはこれらの定義を複数の Fortran プログラムで共有することができます。
プログラムには,適切な USE 文に加えて,関数呼び出しやサブルーチン呼び出しを追加する必要があります。
Fortran Module Wizard によって生成されるルーチンは,Fortran から呼び出されることを念頭に置いて設計されています。これらのルーチンは,(Fortran から呼び出されることを念頭に置いて設計されていない) 適切なシステム・ルーチンを呼び出して,COM およびオートメーション・オブジェクトを使用するために必要なコーディングを単純化します。
Visual Fortran は,Fortran プログラマに,COM およびオートメーション機能の高水準の抽象化を提示する実行時ルーチンの組を提供しています。ウィザードが生成する Fortran インタフェースは,オートメーション・オブジェクトと COM オブジェクトの違いの大部分をわからないようにします。
指定したオプションに応じて,生成されたコードには次表に示したルーチンが含まれます。プログラマはこれらのルーチンを呼び出すことで,COM またはオートメーション・オブジェクトを使用することができます。
DFCOM ルーチン (COMxxxxx) | |
COMAddObjectReference | オブジェクトのインタフェースに引用を追加します。 |
COMCLSIDFromProgID | プログラマティック識別子を渡し,対応するクラス識別子を返します。 |
COMCLSIDFromString | クラス識別子文字列を渡し,対応するクラス識別子を返します。 |
COMCreateObjectByGUID | クラス識別子を渡し,オブジェクトのインスタンスを作成します。オブジェクトのインタフェースへのポインタを返します。 |
COMCreateObjectByProgID | プログラマティック識別子を渡し,オブジェクトのインスタンスを作成します。オブジェクトの IDispatch インタフェースへのポインタを返します。 |
COMGetActiveObjectByGUID | クラス識別子を渡し,現在活動状態のオブジェクトのインタフェースへのポインタを返します。 |
COMGetActiveObjectByProgID | プログラマティック識別子を渡し,現在活動状態のなオブジェクトの IDispatch インタフェースへのポインタを返します。 |
COMGetFileObject | ファイル名を渡し,ファイルを操作できるオートメーション・オブジェクトの IDispatch インタフェースへのポインタを返します。 |
COMInitialize | COM ライブラリーを初期化します。他の COM または AUTO ルーチンを呼び出す前に,ライブラリーを初期化する必要があります。 |
COMIsEqualGUID | 2 つの GUID が等しいかどうかを決定します。 |
COMQueryInterface | インタフェース識別子を渡し,オブジェクトのインタフェースへのポインタを返します。 |
COMReleaseObject | プログラムがオブジェクトのインタフェースへの引用の終了を通知します。 |
COMStringFromGUID | GUID を渡し,対応する文字説明を返します。 |
COMUninitialize | COM ライブラリーを非初期化します。これは最後に呼び出す COM ルーチンでなくてはなりません。 |
DFAUTO オートメーション・ルーチン (AUTOxxxxx) | |
AUTOAddArg | 引数名と値を渡し,引数を引数並びデータ構造に追加します。 |
AUTOAllocateInvokeArgs | AUTOInvoke に渡すことになる引数を保持する引数並びデータ構造を割り付けます。 |
AUTODeallocateInvokeArgs | 引数並びデータ構造の割り付けを解除します。 |
AUTOGetExceptInfo | メソッドが例外状態を返したときに,例外情報を取得します。 |
AUTOGetProperty | プロパティの名前または識別子を渡し,オートメーション・オブジェクトのプロパティ値を取得します。 |
AUTOGetPropertyByID | プロパティのメンバ ID を渡し,オートメーション・オブジェクトのプロパティ値を引数並びの第 1 引数として取得します。 |
AUTOGetPropertyInvokeArgs | 引数並びデータ構造を渡し,オートメーション・オブジェクトの引数並びの第 1 引数で指定されたプロパティの値を取得します。 |
AUTOInvoke | オブジェクトのメソッドの名前または識別子と,引数並びデータ構造を渡します。渡された引数を使ってメソッドを呼び出します。 |
AUTOSetProperty | プロパティの名前または識別子と値を渡します。オートメーション・オブジェクトのプロパティ値を設定します。 |
AUTOSetPropertyByID | プロパティのメンバ ID を渡し,オートメーション・オブジェクトの引数並びの第 1 引数を使ってプロパティの値を設定します。 |
AUTOSetPropertyInvokeArgs | 引数並びデータ構造を渡し,オートメーション・オブジェクトの引数並びの第 1 引数で指定されたプロパティの値を設定します。 |
Visual Fortran サンプルとしては,Fortran Module Wizard の使い方を示すいくつかのプロジェクトが ...\DF98\SAMPLES\ADVANCED\COM フォルダにあります。次に例を示します。
AUTODICE:オートメーションを使って Microsoft Excel 97 を起動し,Fortran データからグラフを作成します。
DSBUILD:オートメーションを使ってビジュアル開発環境を起動し,プロジェクト構成を再ビルドします。
DSLINES:COM を使ってビジュアル開発環境を起動し,Fortran ソース・ファイルを編集して,Debug 行 (列1) を IFDEF 命令に変換します。
IWEB:COM インタフェースを使って Web ブラウザを起動し,ブラウザに対して指定された URL を開くように指示します。
DSLINES サンプルが使用する生成されたコードの例
DSLINES サンプルには,COM インタフェースを使って,この機能やその他の Microsoft ビジュアル開発環境機能を呼び出すコードが含まれています。
次のコードは,Fortran Module Wizard が ...\COMMON\MSDEV98\BIN\devshl.dll の COM タイプ情報から生成するコードの注釈付きのバージョンです。この COM タイプ情報は,Microsoft ビジュアル開発環境オブジェクト・モデルの最上位オブジェクトを記述しています。
INTERFACE ! ドキュメントをディスクに保存します。 INTEGER*4 FUNCTION IGenericDocument_Save($OBJECT, vFilename, & & vBoolPrompt, pSaved) USE DFCOMTY INTEGER*4, INTENT(IN) :: $OBJECT ! オブジェクト・ポインタ !DEC$ ATTRIBUTES VALUE :: $OBJECT TYPE (VARIANT), INTENT(IN) :: vFilename ! (省略可能な引数) !DEC$ ATTRIBUTES VALUE :: vFilename TYPE (VARIANT), INTENT(IN) :: vBoolPrompt ! (省略可能な引数) !DEC$ ATTRIBUTES VALUE :: vBoolPrompt INTEGER*4, INTENT(OUT) :: pSaved ! Void !DEC$ ATTRIBUTES REFERENCE :: pSaved !DEC$ ATTRIBUTES STDCALL :: IGenericDocument_Save END FUNCTION IGenericDocument_Save END INTERFACE ! ルーチン・ポインタ POINTER(IGenericDocument_Save_PTR, IGenericDocument_Save)
この例に関する注意
タイプ情報がメンバ関数を記述するコメントを提供する場合,そのコメントは手続が始まる前に置かれます。 | |
手続への第 1 引数はつねに $OBJECT です。これはオブジェクトのインタフェースへのポインタです。残りの引数名はタイプ情報から決定されます。オブジェクトのインタフェースへのポインタを入手する方法については,「オブジェクトのインタフェースへのポインタの取得」を参照してください。 | |
これは,引数の呼び出し規約を指定するために使用される ATTRIBUTE コンパイラ指示文の例です。 | |
VARIANT は,任意の形式のオートメーション・データを格納できるデータ構造です。ここには,データの形式を識別する欄と,データ値を保持する共用体が含まれています。VARIANT 引数を使用することで,呼び出し側はメンバ関数が期待しているデータ型への変換が可能な任意のデータ型を使用することができます。 | |
ほぼすべての COM メンバ関数は,HRESULT 型の状態を返します。このため,COM メンバ関数が出力を生成するときには,出力引数を使って値を返します。この例では,"pSaved" 引数はルーチン特有の状態値を返します。 | |
COM メンバ関数のインタフェースは,ダイナミック・リンク・ライブラリー関数のインタフェースとよく似ていますが,1 つの大きな違いがあります。DLL 関数とは異なり,COM メンバ関数のアドレスは,プログラムのリンク時には不明です。このためオブジェクトのインタフェースへのポインタを実行時に取得し,これをもとにメンバ関数のアドレスを計算する必要があります。 |
次の例は,Fortran Module Wizard が "Save" 関数のために生成するラッパの注釈付き版を示しています。ラッパの名前は,対応するメンバ関数の名前の前に "$" の文字を付けたものです。
! ドキュメントをディスクに保存します。 INTEGER*4 FUNCTION $IGenericDocument_Save($OBJECT, vFilename, & & vBoolPrompt, pSaved) !DEC$ ATTRIBUTES DLLEXPORT :: $IGenericDocument_Save IMPLICIT NONE INTEGER*4, INTENT(IN) :: $OBJECT ! オブジェクト・ポインタ !DEC$ ATTRIBUTES VALUE :: $OBJECT TYPE (VARIANT), INTENT(IN), OPTIONAL :: vFilename !DEC$ ATTRIBUTES REFERENCE :: vFilename TYPE (VARIANT), INTENT(IN), OPTIONAL :: vBoolPrompt !DEC$ ATTRIBUTES REFERENCE :: vBoolPrompt INTEGER*4, INTENT(OUT) :: pSaved ! Void !DEC$ ATTRIBUTES REFERENCE :: pSaved INTEGER*4 $RETURN INTEGER*4 $VTBL ! インタフェース関数表 POINTER($VPTR, $VTBL) TYPE (VARIANT) :: $VAR_vFilename TYPE (VARIANT) :: $VAR_vBoolPrompt IF (PRESENT(vFilename)) THEN $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 ! インタフェース関数表 $VPTR = $VTBL + 84 ! ルーチン表オフセットを追加します。 IGenericDocument_Save_PTR = $VTBL $RETURN = IGenericDocument_Save($OBJECT, $VAR_vFilename, & & $VAR_vBoolPrompt, pSaved) $IGenericDocument_Save = $RETURN END FUNCTION $IGenericDocument_Save
この例に関する注意
ラッパはメンバ関数インタフェースと同じ引数名を取ります。 | |
ラッパは,インタフェース・ポインタと,インタフェースのタイプ情報に含まれるオフセットから,メンバ関数のアドレスを計算します。実装用語としてインタフェース・ポインタとは,"Interface Function Table" と呼ばれる関数ポインタの配列へのポインタを引用するポインタのことです。 | |
COM または AUTO ルーチンの引数は省略可能です。ラッパは呼び出しの細部を処理し,呼び出しに含まれていない省略可能な引数を自動的に指定します。 | |
"Save" メンバ関数のオフセットは 84 です。コードは計算されたアドレスを,前の例で宣言した関数ポインタ IGenericDocument_Save_PTR に代入した後に,関数を呼び出します。 |
DSLINES サンプルには,この機能やその他の Microsoft ビジュアル開発環境機能を,COM インタフェースを使って呼び出すコードが含まれています。
DSBUILD サンプルが使用する生成されたコード例
DSBUILD サンプルには,この機能やその他の Microsoft ビジュアル開発環境機能を,オートメーション・インタフェースを使って呼び出すコードが含まれています。
次の例は,...\COMMON\MSDEV98\BIN\devshl.dll にあるオートメーション・タイプ情報から Fortran Module Wizard が生成するコードの注釈付き版を示しています。
! 指定した構成ですべてのファイルを再ビルドします。 SUBROUTINE IApplication_RebuildAll($OBJECT, Configuration, $STATUS) !DEC$ ATTRIBUTES DLLEXPORT :: IApplication_RebuildAll IMPLICIT NONE INTEGER*4, INTENT(IN) :: $OBJECT ! オブジェクト・ポインタ !DEC$ ATTRIBUTES VALUE :: $OBJECT TYPE (VARIANT), INTENT(IN), OPTIONAL :: Configuration !DEC$ ATTRIBUTES REFERENCE :: Configuration INTEGER*4, INTENT(OUT), OPTIONAL :: $STATUS ! メソッド状態 !DEC$ ATTRIBUTES REFERENCE :: $STATUS INTEGER*4 $$STATUS INTEGER*4 invokeargs invokeargs = AUTOALLOCATEINVOKEARGS() IF (PRESENT(Configuration)) CALL AUTOADDARG(invokeargs, '$ARG1', & & Configuration, .FALSE.) $$STATUS = AUTOINVOKE($OBJECT, 28, invokeargs) IF (PRESENT($STATUS)) $STATUS = $$STATUS CALL AUTODEALLOCATEINVOKEARGS (invokeargs) END SUBROUTINE IApplication_RebuildAll
この例に関する注意
手続への第 1 引数はつねに $OBJECT です。これは,オートメーション・オブジェクトの IDispatch インタフェースへのポインタです。手続への最後の引数はつねに $STATUS です。これは,メソッドの戻り状態を確認したいときに指定できる省略可能な引数です。IDispatch Invoke メンバ関数は HRESULT 型の状態を返します。HRESULT は 32 ビット値です。これは Win32 のエラー・コードと同じ構造を持っています。$OBJECT 引数と $STATUS 引数の間には,タイプ情報から決定されたメソッド引数の名前が含まれています。タイプ情報は引数の名前を含んでいないこともあります。この場合,Fortran Module Wizard は "$ARGn" という名前を作成します。 | |
AUTOAllocateInvokeArgs は,ユーザーがメソッドに渡す引数を収集するために使われるデータ構造を割り付けます。AUTOAddArg はこのデータ構造に引数を 1 つ追加します。 | |
AUTOInvoke は,引数並びを渡して,指定されたメソッドを呼び出します。これにより状態の結果が返されます。 | |
呼び出し側が状態引数 (STATUS) を指定した場合,コードはそこに状態の結果をコピーします。 | |
AUTODeallocateInvokeArgs は,引数並びデータ構造が使用するメモリーの割り付けを解除します。 |
...\DF98\SAMPLES\ADVANCED\COM フォルダの DSBUILD サンプルには,この機能や,その他の Microsoft ビジュアル開発環境機能を,オートメーション・インタフェースを使って呼び出すコードが含まれています。