インテル® Fortran コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
インテル® Fortran ハンドラーがどのようにアプリケーションに取り込まれるか、また、プログラマーが定義したハンドラーをどのようにアプリケーションに取り込むかを理解するには、それぞれのアプリケーションがどのように構成されているかを理解する必要があります。このセクションでは、さまざまな種類のアプリケーション (プロジェクト) で使用されるハンドラーについて説明します。
Fortran コンソール・アプリケーションは、C の main() 関数を提供するインテル® Fortran ランタイムシステムを使用するので、C アプリケーションに似ています。
コンソール・アプリケーションのエントリーポイントは、C ライブラリーの mainCRTStartup() ルーチンとして指定されます (C ランタイムソース内の crt0.c モジュールを参照してください)。このルーチンは、C ランタイムシステムを初期化し、C ランタイム例外フィルター (_XcptFilter()) を使用する Try-Except 構文で Fortran ランタイムシステムの main() を囲み、ランタイムモジュール for_main.c で Fortran ランタイムシステムの main() を呼び出します。簡単な例を次に示します。
mainCRTStartup() { C initialization code here __try { more initialization code here mainret = main() /* Fortran ランタイムの main() を呼び出す */ exit(mainret) } __except ( _XcptFilter() ) { _exit ( GetExceptionCode() ) } }
Fortran ランタイムシステムでは、main() が Fortran ランタイムシステムを初期化し (まだ初期化されていない場合)、例外が発生したときに Fortran ランタイムシステムのデフォルトハンドラーを起動するフィルター式を持つ Try-Except 構文で MAIN__ (Fortarn コードのエントリーポイント) を囲み、そこから MAIN__ を呼び出します。さらに、これらすべてを Try-Finally 構文で囲み、プログラムが終了したときにランタイムシステムのクリーンアップ (for_rtl_finish_ を使用) を実行します。簡単な例を次に示します。
main() { __try { __try { for_rtl_init() MAIN__ } __except ( expression-invoking-fortran-default-handler ) { } } __finally { for_rtl_finish() } }
Fortran コードでは、MAIN__ シンボルは、ランタイムシステムの main() ルーチンに呼び出されるエントリーポイントです。MAIN__ には、追加のランタイムの初期化または検証を行うためのコードが含まれます。例えば、デフォルトではない fpe[:]0 オプションを使用してコンパイルした場合、浮動小数点例外の設定/処理動作方法をランタイムシステムに伝えるために、FOR_SET_FPE が呼び出されることがあります。
(Fortran スタンダード・グラフィックスを含む) Fortran QuickWin アプリケーションは、インテル® Visual Fortran が WinMain() 関数を提供する特殊な Windows* アプリケーションです。
QuickWin アプリケーションのエントリーポイントは、C ライブラリーの WinMainCRTStartup() ルーチンとして指定されます (C ランタイムソース内の crt0.c モジュールを参照してください)。このルーチンは、C ランタイムを初期化し、C ランタイム例外フィルター (_XcptFilter()) を使用する Try-Except 構文で、インテル® Visual Fortran 定義の WinMain() を囲み、そこから WinMain() ルーチンを呼び出します。簡単な例を次に示します。
WinMainCRTStartup() { C initialization code here __try { more initialization code here mainret = WinMain() /* qwin ライブラリーの WinMain() を呼び出す */ exit(mainret) } __except ( _XcptFilter() ) { _exit ( GetExceptionCode() ) } }
QuickWin ライブラリーでは、WinMain() が、QuickWin 固有の初期化の一部を実行し、QWINForkMain から実行を開始するスレッドを新規作成してから、動作を命令するメッセージループに入ります。メッセージループは、例外が発生したときに Fortran ランタイムシステムのデフォルトハンドラーを起動する Try-Except_Finally 構文で囲まれ、終了時に for_rtl_finish_ を呼び出します。他のスレッドで実行している QWINForkMain() は、Fortran ランタイムシステムの main() を呼び出します。main() からは、MAIN__ が呼び出されます。簡単な例を次に示します。
WinMain() { Initialization code here BeginThreadEx (..., QWINForkMain, ... ) __try { __try { the message loop... for_rtl_finish() return (msg.wParam) } __except ( expression-invoking-default-fortran-handler ) { } } __finally { for_rtl_finish() return (msg.wParam) } }
QWINForkMain は次のようになります。
QWINForkMain() { main() /* MAIN__ を呼び出す CVF rtl main() を呼び出す */ cleanup and exit... }
main() ルーチンおよび MAIN__ ルーチンは、上記の「Fortran コンソール・アプリケーション」で説明されているものと同じです。
Fortran DLL は、通常、ほかのメインプログラムから呼び出される 1 つ以上のルーチンの集まりです。これらのルーチンは、DLL を呼び出すコードによって作成された構造と環境で実行されます。DllMain() 関数を使用して DLL を初期化することもできますが、一般的なアプリケーションの初期化はメインプログラムから制御したほうが良いでしょう。
DLL では、例外ハンドラーは自動的に提供されません。プログラマーが自分で提供しない限り、環境の初期化は行われません。メイン・アプリケーションも Fortran で記述されている場合は、そのアプリケーションによって提供されるデフォルトの Fortran ハンドラーを使用できます。
Fortran ウィンドウ・アプリケーションでは、エントリーポイントとして WinMainCRTStartup() が使用されます。各ユーザーは、WinMain 関数の宣言とインターフェイス用のコードを作成する必要があります。この後にある Fortran コードの例を参照してください。コンパイラーは、初期化コードを含む MAIN__ シンボルを生成しますが、この MAIN__ が呼び出されることはありません。また、ランタイムシステムの main() も呼び出されません。そのため、インテル® Visual Fortran のデフォルトハンドラーをフックする Try-Except 構文はありませんし、ランタイムシステムの初期化とクリーンアップもありません。簡単な例を次に示します。
WinMainCRTStartup() { C initialization code __try { more initialization code mainret = WinMain() /* ユーザーの WinMain() を呼び出す */ exit(mainret) } __except ( _XcptFilter() ) { _exit ( GetExceptionCode() ) } }
Fortran コードは次のようになります。
integer(4) function WinMain( HANDLE, HANDLE, LPSTR, int ) ... ! ユーザーによって記述される任意の Fortran コード... ... end