バイナリ互換インターフェースの使用によるOMLライブラリの記述

上記のBCIインターフェースの拡張として、このトピックではFortranコードをOML関数に変換する方法について説明します。

以下の手順に従って、FortranルーチンからOMLライブラリを記述します:
  1. Fortranソースコードをオブジェクトにコンパイルします。

    Fortranコンパイラを使って、myFortransub.fmyFortransub.oにコンパイルします。

  2. C/C++ 標準ライブラリOMLInterfacePublic.hを Projectフォルダーに追加します。
  3. Fortran関数の引数に従ってC/C++ファイルを作成します。

    C/C++ファイルには以下が含まれている必要があります:

    • 使用するOMLヘッダー(OMLInterfacePublic.h)。
    • Extern “C”ブロック。
    • InitToolbox関数。
    • Fortran関数を呼び出すC/C++ 関数。
  4. コンパイルされたFortranファイルをプロジェクトにリンクします。
  5. C/C++コードをコンパイルしてDLLファイル(例えば omlFortran.dll)を作成します。
  6. プロジェクトフォルダーに、Fortranコンパイル時に呼び出された/使用されたFortran DLLを追加します。
  7. 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の引数はすべて参照渡しです。
  • 関数名にアンダースコアが追加されることに注意してください。