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

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

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

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

  2. 標準C/C++ ライブラリOMLInterfacePublic.hをプロジェクトフォルダーに追加します。
  3. Fortran 関数引数にしたがってC/C++ファイルを作成します。

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

    • 使用されるOMLヘッダー(OMLInterfacePublic.h)。
    • Extern “C” ブロック。
    • InitToolbox関数。
    • Fortran関数を呼ぶC/C++関数。
  4. コンパイル済みFortranファイルをProjectにリンクします。
  5. C/C++コードをコンパイルし、DLLファイル(omlFortran.dllなど)を作成します。
  6. Projectフォルダーに、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);
NoteColonSymbol
  • Fortranでは、関数の引数はすべて参照によって渡されます。
  • 関数名に追加された余分なアンダースコア文字に注意してください。