Write a Fortran OML Library Using the Binary-compatible Interface

As an extension of the BCI interface exposed above, this topic describes how to turn Fortran code into an OML function.

Follow these steps to write an OML library from a Fortran routine:
  1. Compile the Fortran source code into an object.

    Using a Fortran compiler, compile myFortransub.f into myFortransub.o.

  2. Add the standard C/C++ library OMLInterfacePublic.h to the Project folder.
  3. Create a C/C++ file according to the Fortran function arguments,

    The C/C++ file must contain:

    • OML header to be used (OMLInterfacePublic.h).
    • Extern ā€œCā€ block.
    • InitToolbox function.
    • C/C++ function calling the Fortran function.
  4. Link the compiled Fortran file to the Project.
  5. Compile the C/C++ code to create the DLL file (for example, omlFortran.dll).
  6. To the Project folder, add the Fortran DLL that was called/used upon the Fortran compilation.
  7. Import the DLL with the addlibrary function.

Example - Fortran Routine Compiled and Added to OML

The Fortran routine in this example is 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
The C++ code (leveraging the BCI OML APIs) is 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;
}
The call to the Fortran routine is made by:
myfortransub_(&input1, &input2, &input3, &output1);
Note:
  • In Fortran, the Function arguments are all passed by reference.
  • Notice the extra underscore character added to the function name.