Visual Basic から Visual Fortran DLL を呼び出すときに重要な,引数渡しとデータ型に関する注意事項を次に示します。
Visual Basic は,引数を渡すときには STDCALL 標準を使用します。ただし唯一の例外として,ia32 システムでは,名前に @n のカウントを追加しません。
Visual Basic の中で呼び出されるルーチンと渡される引数の名前を宣言します。スカラの数値引数は,Basic から直接渡し,Fortran で直接使用することができますが,文字列,配列,および型の場合には余分な処理が必要です。
この説では,以下の内容について説明しています。
Visual Basic での Fortran ルーチンの宣言
Basic で Fortran ルーチンを宣言すると,ルーチン名は宣言されたときと同じ大文字小文字の組み合わせでエクスポートされます。オプションとして,宣言中で Fortran DLL へのディレクトリ・パスを指定することができます。
次の Visual Basic の例は,2 つの単精度引数を取る,FortranCall という名前の Fortran サブルーチンを宣言しています。
Declare Sub FortranCall Lib "d:\My Projects\FCall.dll" (A1 as Single, A2 as Single)
次の例は,2 つの整数 (32 ビット) 引数を取り単精度値を返す,FortranFunc という名前の Fortran 関数を宣言しています。
Declare Function FortranFunc Lib "d:\My Project\FFun.dll" (A1 as Long, A2 as Long) As Single
Fortran DLL を作成するときには,DLL 外から参照できるように,関数またはサブルーチン宣言に 2 つの属性を追加する必要があります。
Fortran ルーチン名は DLL からエクスポートされなくてはならず,Basic が期待する名前と正確に一致するように別名化されなくてはなりません。ATTRIBUTES (cDEC$ ATTRIBUTES コンパイラ指示文) と ALIAS 宣言は,次の Fortran サブルーチンのように,名前と別名をエクスポートします。
SUBROUTINE FortranCall !DEC$ ATTRIBUTES DLLEXPORT :: FortranCall ! これが名前をエクスポート !DEC$ ATTRIBUTES ALIAS : "FortranCall" :: FortranCall ! これがそれを設定
これは Fortran 関数にも当てはまります。Fortran 関数の場合も,エクスポートされ,Basic が期待する名前と正確に一致するように別名化されなくてはなりません。
REAL Function FortranFunc !DEC$ ATTRIBUTES DLLEXPORT :: FortranFunc !DEC$ ATTRIBUTES ALIAS : "FortranFunc" :: FortranFunc
Visual Basic と Visual Fortran の間でデータを渡すときには,この 2 つの言語が使用する呼び出し標準,データの大きさ,およびデータのディスク上の書式に注意する必要があります。
次表に,各種のデータ型の呼び出しに関する注意事項を要約します。
データ型 | 呼び出しに関する注意事項 |
整数 | 基本設定では,Visual Basic と Visual Fortran の両方が,整数を参照で渡します。Basic の基本整数型の大きさは 2 バイトで,Fortran の INTEGER(2) と等価です。整数型の引数の参照には,どちらの言語でも余分な操作は必要ありません。 |
浮動小数点 | 基本設定では,Visual Basic と Visual Fortran の両方が,単精度および倍精度浮動小数点数を参照で渡します。単精度浮動小数点数の大きさは,どちらの言語でも 4 バイトです。倍精度浮動小数点数の大きさは,どちらの言語でも 8 バイトです。浮動小数点型の引数の参照には,どちらの言語でも余分な操作は必要ありません。 |
論理 | 基本設定では,Visual Basic と Visual Fortran の両方が,論理型のデータを参照で渡します。Basic の基本論理型の大きさは 2 バイトで,Fortran の LOGICAL(2) と等価です。論理型の引数の参照には,どちらの言語でも余分な操作は必要ありません。 |
文字列 | Basicは,基本設定では,文字列を BSTR という名前の構造体に入れて渡します。Fortran は,基本設定では,文字列を 2 つの引数に入れて渡します。文字列のアドレスと,文字列の長さを含んでいる隠された引数です。これらの基本設定は,Basic の宣言に,またときには Fortran の宣言にも変更を加えることで簡単に置換することができます。
文字列を Basic から Fortran に渡すときには,渡し方の機構を ByVal として宣言するようにしてください。後述の「文字列の渡し方の例」を参照してください。 |
配列 | Basic の配列は,基本設定では 0 を基本とします。Fortran の配列は,基本設定では 1 を基本とします。Basic 配列を大きさ "n" として宣言すると,0 番目の要素を含めて,n+1 個の要素が割り当てられます。これは,後述の「配列の渡し方の例」に示したように置換することができます。
Basic から Fortran に数値の配列を渡すときには,それらが整数であれ浮動小数点数であれ,最初の要素を渡すようにします。Fortran コードでは,引数を配列として宣言します。通常,Basic コードは配列中の要素の数を渡します。 Basic から Fortran に文字列または型の配列を渡すためには,COM ユーティリティを使って,Basic が作成する構造体を読み取る必要があります。配列は Basic から渡され,後に Fortran コード中で SafeArrayxx ユーティリティを使って抽出されます。詳細については,...\DF98\SAMPLES\MIXLANG\VB\ARRAYS および ...\DF98\SAMPLES\MIXLANG\VB\TYPEARRAYS フォルダの Visual Fortran サンプルを参照してください。 |
型 | Basic で宣言した型は,Basic から Fortran に渡すことができます。Basic で宣言した型は,Fortran の中でも宣言しなくてはなりません。この 2 つの構造体が同じになるように注意する必要があります。Fortran では,TYPE は,通常は PACK:2 を使って,詰め込まれるように宣言します。2 言語の TYPE 要素の基本の大きさに注意し,基本設定を適宜調整する必要があります。
Basic で宣言した型に含まれる文字列は Unicode として格納されることに注意してください。これは Fortran では INTEGER*2 の配列として宣言することができます。これらの文字列を Fortran から参照するには,Natural Language System (NLS) API 呼び出しを使用します。詳細については,「National Language Support ルーチンの使用」と,...\DF98\SAMPLES\MIXLANG\VB\TYPEARRAYS フォルダの Visual Fortran サンプルを参照してください。 |
次の例は,通常の文字列の渡し方を示しています。文字列長は可変長で,Fortran に対して ByVal で文字長を渡す必要があります。
Basic コード:
Declare Sub FortString1 Lib "forttest" (ByVal S1 as String, ByVal L1 as Long) Dim S1 as String * 12 Call FortString1(S1, Len(S1))
Fortran コード:
Subroutine FortString1 (mystring) !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortString1" :: FortString1 CHARACTER*(*) mystring
次の例では,文字列長が一定で,Basic と Fortran の両方のコードですでにわかっているので,Fortran に文字長を渡す必要はありませんが,Fortran に対して文字長を期待しないように指示する必要があります。
Basic コード:
Declare Sub FortString2 Lib "forttest" (ByVal S2 as String) Dim S2 as String * 25
Fortran コード:
Subroutine FortString2 (mystring) !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortString2" :: FortString2 !DEC$ ATTRIBUTES REFERENCE :: mystring CHARACTER*25 mystring
次の例は,配列の渡し方を示しています。
Basic コード:
Declare Sub FortArray1 Lib "forttest" (A1 as Long, NumElem as long) Dim A1(1:3) as Long Call FortArray1(A1(1), 3)
Fortran コード:
Subroutine FortArray1 (Array1, N) !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortArray1" :: FortArray1 Integer array1(N)