4

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

  • 在 Matlab 中创建 *.m 脚本
  • 确保脚本与 Matlab Coder 兼容。
  • 使用 Matlab Coder 生成 C++ 共享库 (DLL)
  • 使用以下方式与 C# 集成:

    //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();
    }
    
  • 另外,我希望能够停止执行并检索一些部分结果。为此,我考虑了两种方法:StopExecutionRetrievePartialResults

    [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();
    

有可能吗?如果没有,是否有任何替代方案?如果是,我在哪里可以找到更多示例?

4

5 回答 5

3

我已经做了两种方式。以前,我们的项目使用 MATLAB Compiler,但我们现在切换到 Coder,因为这避免了必须安装运行时的开销(顺便说一句,它经常无缘无故无法在进程内启动)。

我们将编码器输出编译为具有 C 接口的非托管 C 项目,并使用 C++/CLR 项目作为包装器。这样做的好处是我们不需要手动指定 P/Invoke 的接口,因为编译器会直接读取头文件。C++/CLR 程序集链接到将在其中使用代码的 C# 项目。请注意,这有点昂贵,因此请尽量避免在紧密循环中调用 matlab 代码,如果可能的话,最好将整个循环移到库中。

这是包装库中的一个片段(仍然使用旧的托管 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;
}
于 2013-10-22T06:21:09.577 回答
3

我不知道你的计划是否可行,但 MATLAB Builder NE 可能是一个替代方案。它直接输出一个 .Net dll,对 m 代码没有这些硬限制。

缺点是,目标机器上需要 MCR。

于 2013-10-16T21:11:54.237 回答
2

我认为您编写 DLL 并从 c# 调用它的计划似乎是两种主要方法之一。

替代方案是:

使用 MATLAB 作为 C# 中的自动化服务器,通过 com 自动化使用引擎接口。这使您可以同时从 C# 端和 MATLAB 端调试您的 C# 应用程序,在每一端都使用调试器。

以下是两种方法的示例,甚至是第三种替代方法(似乎不太推荐)。

在文件交换上将 MATLAB 与 C# 集成

于 2013-10-17T10:04:08.627 回答
1

所以以列表的形式,

  1. 我怀疑您是否能够停止 matlab 代码,除非您将其分解为多个函数,您可以根据需要调用这些函数。
  2. 您应该能够通过调用线程并根据需要停止线程来停止执行,或者更好的是,发送一个信号让线程停止,它将在函数之间中止(为了部分结果)
  3. 该 matlab 是一种糟糕的语言,无法满足第 1 项的要求(并不是说我自己有过任何好的经验)
于 2013-10-22T20:27:59.727 回答
1

我已经实现了您要求使用 MATLAB 编译器的确切功能。我对 MATLAB Coder 没有任何经验,但应该是相同的原理。编译 MATLAB 库后,您可以使用 C# 中的 P/Invoke 访问它,就像使用任何其他非托管库一样(并且正如您在问题中指定的那样)。

有几点需要注意:

  1. 我认为您在尝试成功实施“停止执行”策略时可能会遇到设计方面的问题。MATLAB 可执行文件/库旨在从头到尾执行,而无需对运行时进行太多控制。如果您可以将脚本分成多个部分来处理该设计,那可能会更好。

  2. 编译的 MATLAB 库需要您手动“启动”和“停止”MATLAB 组件运行时,以及每个脚本的组件运行时。因此,执行流程将类似于:

    开始MCL();

    StartScript1_Runtime();

    Run_Script1();

    StopScript1_Runtime();

    停止MCL();

如果您在启动整个 MCL 之前尝试运行“Script 1 Runtime”,应用程序将崩溃。因此,您需要小心设计包装类以正确处理它。此外,您要确保在退出应用程序之前停止一切,否则,MCR 将有效地连续看到 2 次“运行”,并且会崩溃。

  1. 您没有在问题中涉及任何输入/输出参数,但在大多数情况下,您将需要使用 MATLAB 函数来创建 MEX 变量以将数据传入/传出 MATLAB 环境。

这里有一组很好的示例源,应该涵盖以上所有内容:http: //www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c

此外,编译器帮助本身有很多有用的资源。 http://www.mathworks.com/help/compiler/shared-libraries.html

于 2013-10-18T20:08:21.830 回答