Вопрос

I want to integrate MATLAB Coder output with a C# project in Visual Studio 2010. My main idea is:

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

Is it possible to do? If no, is there any alternatives? If yes, where can I find more examples?

Это было полезно?

Решение

I have no idea if your plan works, but MATLAB Builder NE might be an alternative. It directly outputs a .Net dll without those hard limitations to the m-code.

The disadvantage is, that MCR is required on the target machine.

Другие советы

I've done both ways. Formerly, our project was using MATLAB Compiler, but we now switched to Coder, because that avoids the overhead of having to install the runtime (which btw often failed to start inside the process for no apparent reason).

We compile the coder output as an unmanaged C project with a C interface and use a C++/CLR project as a wrapper. This has the advantage that we don't need to manually specify the interface for P/Invoke as the compiler will directly read the header files. The C++/CLR assembly is the linked to the C# project where the code is going to be used. Be aware that this is kind of expensive, so try to avoid calling the matlab code in a tight loop and better move the whole loop into the library if that is possible.

Here's a snippet from the wrapper library (still uses old Managed C++ syntax, but that doesn't matter here)

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;
}

I think your plan of writing a DLL and calling it from c# seems to be one of the two main ways to go.

The alternative would be to:

use the MATLAB as an automation server from C# using the engine interface via com automation. This allows you to simultaneously debug your C# application from both the C# side and the MATLAB side, using debuggers on each side.

Here are examples for both methods, and even a third alternate method (that seems less recommended).

Integrating MATLAB with C# on File Exchange

I've achieved the exact functionality you're asking about using the MATLAB Compiler. I don't have any experience with the MATLAB Coder, but should be the same principle. Once you have a MATLAB Library compiled, you can access it using P/Invoke in C# like you would with any other unmanaged library (and as you specified in your question).

Theres a couple of caveats:

  1. I think you might have an issue design-wise trying to successfully implement your "stop execution" strategy. The MATLAB executables/libraries are meant to execute from start to finish without much control over the runtime. If you can split your script up into multiple pieces to handle that design, that may work better.

  2. Compiled MATLAB libraries require you to "Start" and "Stop" the MATLAB Component Runtime manually, as well as a component runtime for each script. So, execution flow, would be something like:

    StartMCL();

    StartScript1_Runtime();

    Run_Script1();

    StopScript1_Runtime();

    StopMCL();

If you attempt to run the "Script 1 Runtime" prior to starting the overall MCL, the app will crash. So, you need to be careful with how you design the wrapper class to handle that properly. Also, you want to be sure to Stop everything before exiting your app, otherwise, the MCR will effectively see 2 "Runs" in a row, and will crash.

  1. You didn't cover any input/output arguments in your question, but in most cases, you will need to use MATLAB functions to create the MEX variables to hand data in/out of the MATLAB environment.

There is a great set of sample source here that should cover all of the above: http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c

Also, the Compiler help itself has a bunch of useful resources. http://www.mathworks.com/help/compiler/shared-libraries.html

So in a list form,

  1. I doubt that you will be able to stop the matlab code unless you break it up into multiple functions, which you may call as needed.
  2. That you should be able to halt execution by calling on a thread and stopping the thread as you need, or better, send a signal for the thread to stop, which it will abort between functions (for the purpose of partial results)
  3. That matlab is a terrible language for fulfilling the requirements on item 1 (not that I have ever had any good experiences with it myself)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top