バイナリ互換インターフェースの使用によるOMLライブラリの記述
上記のBCIインターフェースの拡張として、このトピックではFortranコードをOML関数に変換する方法について説明します。
以下の手順に従って、FortranルーチンからOMLライブラリを記述します:
- Fortranソースコードをオブジェクトにコンパイルします。
Fortranコンパイラを使って、myFortransub.fをmyFortransub.oにコンパイルします。
- C/C++ 標準ライブラリOMLInterfacePublic.hを Projectフォルダーに追加します。
- Fortran関数の引数に従ってC/C++ファイルを作成します。
C/C++ファイルには以下が含まれている必要があります:
- 使用するOMLヘッダー(OMLInterfacePublic.h)。
- Extern “C”ブロック。
- InitToolbox関数。
- Fortran関数を呼び出すC/C++ 関数。
- コンパイルされたFortranファイルをプロジェクトにリンクします。
- C/C++コードをコンパイルしてDLLファイル(例えば omlFortran.dll)を作成します。
- プロジェクトフォルダーに、Fortranコンパイル時に呼び出された/使用されたFortran DLLを追加します。
- addlibrary関数でDLLをインポートします。
例 - FortranルーチンのコンパイルとOMLへの追加
この例のFortranルーチンはmyFortranSub.f90です。
function myFortranSub(Method,Rs,Rz,RF)
IF (Method == 1) THEN
RF = 1/(Rs+Rz)
ELSE IF (Method == 2) THEN
RF = 1/(Rs**2+Rz**2)**.5
ELSE
RF = 1/(Rs+Rz)
END IF
end function myFortranSub
C++コード(BCI OML APIを活用)はdllmain.cppです。
#include "OMLInterfacePublic.h"
extern "C"
{
__declspec(dllexport) int InitToolbox(OMLInterface* eval);
void __stdcall myfortransub_(int*,float*,float*,float*);
}
bool myFortranFunc(OMLInterface* eval, const OMLCurrencyList* inputs, OMLCurrencyList* outputs)
{
if (inputs->Size() != 3)
eval->ThrowError("Wrong number of arguments");
const OMLCurrency* c1 = inputs->Get(0);
const OMLCurrency* c2 = inputs->Get(1);
const OMLCurrency* c3 = inputs->Get(2);
if (!c1->IsScalar())
eval->ThrowError("Invalid input type in argument 1");
if (!c2->IsScalar())
eval->ThrowError("Invalid input type in argument 2");
if (!c3->IsScalar())
eval->ThrowError("Invalid input type in argument 3");
int input1 = (int)c1->GetScalar();
float input2 = (float)c2->GetScalar();
float input3 = (float)c3->GetScalar();
float output1 = 0.0;
myfortransub_(&input1, &input2, &input3, &output1);
outputs->AddScalar(output1);
return true;
}
int InitToolbox(OMLInterface* eval)
{
eval->RegisterFunction("reservefactor", myFortranFunc);
return 0;
}
Fortranルーチンの呼び出しは次のようにして行われます:
myfortransub_(&input1, &input2, &input3, &output1);
注:
- Fortranでは、Functionの引数はすべて参照渡しです。
- 関数名にアンダースコアが追加されることに注意してください。