エクスポート関数の定義


エクスポート関数は目的のPROPATH関数を呼び出すだけの関数である. エクスポート関数を元々のPROPATH関数と同じ名前にすることはできない. 例えばPST関数を呼び出すエクスポート関数であれば,_PSTやGetPSTなどの名前にする. エクスポート関数とPROPATH関数の名前が異なっても, エクスポートするときのエイリアスを定義したり, 呼出し側でもエイリアスを定義することができるので全く問題ない. エクスポート関数であることを宣言するためにコンパイラ固有の拡張命令を用いる. ここでは,Visual Fortranでのエクスポート関数の定義を説明するが, Power Stationの定義もほとんど同じある.

  1. 関数のエクスポート

    例えば,アンモニアPROPATHのPST関数を呼び出すエクスポート関数_PSTは 以下のように定義する. この書式はFortran 90の文法に従っており,各行の先頭に6カラムの空白は不要である.

      Real Function _PST(T)
      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JNH3_PST' :: _PST
      Real T
      _PST = PST(T)
      End Function
    

    この例では,2行目の

      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JNH3_PST' :: _PST
    

    によってこの関数をJNH3_PSTという関数名でエクスポートすることを宣言している. 32bitのWindows用DLLとしてメイクする場合は,必ずSTDCALLを付加しWindows標準の呼出し規約に 従うことを明示しなければならない. Visual BasicはSTDCALL以外の呼出し規約をサポートしていない. ALIASで指定する関数名は,ソースコード中で既に使われているものであっては ならない(マニュアルにはALIASで指定する関数名の制限に関する記述はないが, 既に使われている関数名と同じものを指定した場合,呼出しに失敗するようである).

    なお,Power Stationの場合は,

      !MS$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JNH3_PST' :: _PST
    

    とする. 以下の場合も同様である. 他のエクスポート関数も定義するときは,End Function以下に続けて同様の書式で書く. このファイルをNH3.F90として保存する.

  2. サブルーチンのエクスポート

    呼出し規約としてSTDCALLを指定した場合, 実数型および整数型の引数は基本的に値渡し(仮引数は実引数のコピーであり, 関数内部で仮引数を変更しても実引数には影響がない.)となる. したがって,M-PROPATH,F-PROPATHおよびI-PROPATHに含まれるサブルーチンを エクスポートする場合は注意を要する.

    この場合,戻り値となる引数は参照渡し(仮引数には実引数のアドレスが 渡される.したがって,仮引数と実引数は同一のメモリ領域を指すことになり,関数内部で 仮引数を変更すれば実引数にもその変更が反映される.)として宣言しなければならない. 例えば,M-PROPATHのSUBXYを呼び出す_SUBXYの定義は次のようになる.

      Subroutine _SUBXY(J, T, P, X, Y, VL, VV, HL, HV, SL, SV)
      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JAWMX_SUBXY' :: _SUBXY
      Real T, P
      Real, Pointer :: X, Y, VL, VV, HL, HV, SL, SV
      Integer, Pointer :: J
      Call SUBXY(J, T, P, X, Y, VL, VV, HL, HV, SL, SV)
      End Subroutine
    

    ここでは,単精度実数のX, Y, ... , SVおよび整数のJは戻り値であるから, これらを

       Real, Pointer :: X, Y, VL, VV, HL, HV, SL, SV
       Integer, Pointer :: J
    

    によってポインタとして宣言すれば,参照渡しの引数とすることができる.

  3. 文字および文字列の取扱い

    文字または文字列が引数に含まれる場合も注意を要する. 文字型および文字列型の内部形式はコンパイラによってかなり異なっている. 例えば,Visual Basicでは文字型自体が存在せず,"A"のような1つの文字 であっても長さ1の文字列として扱う(あるいはASCIIコードに変換してByte型(1バイト)として扱う.). Delphiには文字型と文字列型の両方が存在するが, Delphiの文字列型はVisual Basicの文字列型と互換性がない.

    Windows API関数群では,呼出し側との文字列の受け渡しを C言語で使われるヌル終端文字配列へのポインタによって行うのが普通である. この流儀に従えば,例えばアンモニアPROPATHのFC関数を呼び出すための エクスポート関数_FCの定義は次のようになる.

      Real Function _FC(C)
      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JNH3_FC' :: _FC
      Character, Pointer :: C
      _FC = FC(C)
      End Function
    

    すなわち,引数Cを長さ1の文字配列へのポインタとして宣言する. Fortranのポインタはそれが指している変数と同じように扱うことができるので,受け取ったCを そのままFCに渡せばよい. A-PROPATHのFC関数の引数は2文字("MA"など)であるが,この場合の 引数Cは長さ2の文字列へのポインタとして宣言すればよい.

      Real Function _FC(C)
      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS : 'JMAIG_FC' :: _FC
      Character, Pointer :: C*2
      _FC = FC(C)
      End Function
    
DLLのメイク
DLLの呼び出し方法


お問い合わせはメールにて: akasaka@klc.ac.jp

戻る
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送