将Matlab Coder与C#集成

4

我希望将MATLAB Coder的输出与Visual Studio 2010中的C#项目集成。我的主要想法是:

  • Create a *.m script in Matlab
  • Make sure the script is compatible with Matlab Coder.
  • Generate a C++ shared library (DLL) with Matlab Coder
  • Integrate with C# using something like this:

    //Starts the model execution. May take several minutes
    public static class DllHelper
    {
        [DllImport(@"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "Run()")]
        public static extern int Run();
    }
    
  • Also, I would like to be able to stop the execution and retrieve some partial results. To do this, I was thinking in two methods: StopExecution and RetrievePartialResults

    [DllImport(@"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint =     "StopExecution ()")]
    public static extern int StopExecution ();
    
    [DllImport(@"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "RetrievePartialResults()")]
    public static extern MyResults RetrievePartialResults();
    

这能做到吗?如果不能,有没有其他替代方案?如果可以,我在哪里可以找到更多示例?


1
MATLAB Coder可以从您的MATLAB函数生成独立的C/C++代码。您可以像任何其他本地代码一样在C#中使用它:P/Invoke。 - Amro
@Amro,你有这个实现的例子吗?(MATLAB Coder + DLL + P/Invoke)。如果你有,我会给你50分! - guilhermecgs
5个回答

3
我曾经用过这两种方式。以前,我们的项目使用MATLAB编译器,但现在我们转向使用Coder,因为这样可以避免安装运行时所带来的开销(顺便说一下,这个运行时有时会因为没有明显的原因而无法在进程中启动)。
我们将编译后的Coder作为一个未管理的C项目,并使用一个C++/CLR项目作为包装器。这样做的好处是我们不需要手动指定P/Invoke接口,因为编译器将直接读取头文件。C++/CLR程序集被链接到C#项目中,其中将使用该代码。请注意,这样做有点昂贵,因此尽量避免在紧密循环中调用MATLAB代码,并在可能情况下将整个循环移到库中。
以下是包装库的片段(仍使用旧的Managed C++语法,但在这里并不重要)。
bool CTurconConnect2::Init()
{
      // Call the exported function in the library. Imported using a header file. 
      turcon_initialize();
      // Call one of the matlab functions (in this case, the entry function is manually defined 
      // in the C library, to have a clean interface)
      SetParameters(36.0,400.0,20.0,30.0,15.0,40.0,110.0, 0.0, 100.0);
      return true;
}

bool CTurconConnect2::Exit()
{
      turcon_terminate();
      return true;
}

3

我不确定你的计划是否可行,但MATLAB Builder NE可能是一个替代方案。它直接输出一个.NET DLL,没有M代码的硬性限制。

劣势是目标机器上需要安装MCR。


2
我认为你编写一个DLL并从C#中调用它的计划似乎是两种主要方法之一。
另一种选择是:
使用MATLAB作为自动化服务器,通过COM自动化使用引擎接口从C#中调用。这允许您同时从C#端和MATLAB端使用调试器调试您的C#应用程序。
以下是两种方法的示例,甚至还有第三种备选方法(似乎不太推荐)。
这里提供了两种方法的示例以及第三种备选方法的链接(似乎不太推荐)。 Integrating MATLAB with C# on File Exchange

1

那么以列表形式,

  1. 我怀疑你能否停止Matlab代码,除非你将它拆分成多个函数,并根据需要调用。
  2. 你应该能够通过调用线程并在需要时停止线程来停止执行,或更好地,发送信号让线程停止,在函数之间中断(为了部分结果的目的)。
  3. Matlab是不适合实现第1项要求的可怕语言(不是我自己曾经有过任何良好的经验)。

1
我已经使用MATLAB编译器实现了您要求的确切功能。 我没有使用MATLAB编码器的经验,但原理应该相同。 一旦您编译了MATLAB库,就可以像处理其他未管理的库一样在C#中使用P / Invoke访问它(正如您在问题中指定的那样)。
有几个注意事项:
1. 我认为您在设计上可能会遇到问题,试图成功实现“停止执行”策略。 MATLAB可执行文件/库的运行是从开始到结束而没有太多对运行时的控制。 如果您可以将脚本拆分成多个部分来处理该设计,那么可能效果更好。
2. 编译的MATLAB库需要您手动“启动”和“停止”MATLAB组件运行时,以及每个脚本的组件运行时。 因此,执行流程将类似于:
StartMCL();
StartScript1_Runtime();
Run_Script1();
StopScript1_Runtime();
StopMCL();
如果在启动整个MCL之前尝试运行“Script 1 Runtime”,应用程序将崩溃。因此,您需要小心设计包装器类以正确处理它。另外,在退出应用程序之前,您需要确保停止所有内容,否则,MCR将有效地看到连续两个“Runs”,并且会崩溃。
您的问题中没有涵盖任何输入/输出参数,但在大多数情况下,您需要使用MATLAB函数创建MEX变量来传递数据进出MATLAB环境。
这里有一组很好的示例源代码,应该涵盖了上述所有内容:http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c 此外,编译器帮助本身也有许多有用的资源。http://www.mathworks.com/help/compiler/shared-libraries.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接