4.3 Step 3: Accessing the functions in the engine core

The third step is to implement the MyEngineDLLAccess class (Figure 9).


Fig 9. MyEngineDllAccess class

Because you are using a C# implementation of OpenMI, your engine needs to be accessible from .NET. In the pattern shown above this is handled in two wrappers, MyEngineDLLAccess and MyEngineDotNetAccess. The MyEngineDLLAccess class will make a one-to-one conversion of all exported functions in the engine core code to public .NET methods. The MyEngineDotNetAccess class will change some of the calling conventions.

The specific implementation of the MyEngineDLLAccess class depends on the compiler you are using. Start by implementing export methods for the Initialize, PerformTimeStep, and Finish functions.

The code listed below shows an example of such an implementation for the Simple River Fortran engine. Note that this implementation corresponds to a particular Fortran compiler; the syntax may vary between compilers.

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Wrapper
{

	public class SimpleRiverEngineDllAccess
	{

		[DllImport(@"Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Engine.dll",
			 EntryPoint = "INITIALIZE",
			 SetLastError=true,
			 ExactSpelling = true,
			 CallingConvention=CallingConvention.Cdecl)]
		public static extern bool Initialize(string filePath, uint length);

		[DllImport(@"Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Engine.dll",
			 EntryPoint = "FINISH",
			 SetLastError=true,
			 ExactSpelling = true,
			 CallingConvention=CallingConvention.Cdecl)]
		public static extern bool Finish();


		[DllImport(@"Oatc.OpenMI.Examples.ModelComponents.SimpleRiver.Engine.dll",
			 EntryPoint = "PERFORMTIMESTEP",
			 SetLastError=true,
			 ExactSpelling = true,
			 CallingConvention=CallingConvention.Cdecl)]
		public static extern bool PerformTimeStep();

	}
}
  • No labels