2015-10-18 125 views
-1

我有一个使命,即从C++ poject调用Matlab函数。我知道有几种方法可以做到这一点,我更喜欢通过Matlab引擎来使用它。C++与Matlab引擎之间的连接丢失

  1. 我有几个m文件工作完美的Matlab环境。

    mymat.m

    function myfig() 
        figure; 
    end 
    
  2. 我制成在C++中的DLL包装到第m文件和C++连接。

    dllwrap.h

    #pragma once 
    
    #include <Engine.h> 
    
    #pragma comment (lib,"libmx.lib") 
    #pragma comment (lib,"libmat.lib") 
    #pragma comment (lib,"libeng.lib") 
    #pragma comment (lib,"libmex.lib") 
    
    #ifdef DLLWRAP_EXPORTS 
    #define DLLWRAP_API __declspec(dllexport) 
    #else 
    #define DLLWRAP_API __declspec(dllimport) 
    #endif 
    
    DLLWRAP_API bool TestDll(); 
    DLLWRAP_API void MyFigure(); 
    

    dllwrap.cpp

    #include "stdafx.h" 
    #include "dllwrap.h" 
    
    Engine* pEng = NULL; 
    
    void StartVirtualEngineMatlab() 
    { 
        if ((pEng = engOpen(NULL)) == NULL) 
        { 
         MessageBoxA(NULL, (LPSTR)"Can't start MATLAB engine!", (LPSTR) "MatLab Engine: ERROR!", MB_OK | MB_ICONSTOP); 
         return; 
        }; 
        return; 
    } 
    
    void StopedVirtualEngineMatlab() 
    { 
        engClose(pEng); 
        return; 
    } 
    
    DLLWRAP_API bool TestDll() 
    { 
        if (pEng == NULL) return false; 
        return true; 
    } 
    
    DLLWRAP_API void MyFigure() 
    { 
        engEvalString(pEng, "myfig();"); 
    } 
    

    dllmain.cpp

    #include "stdafx.h" 
    #include "dllwrap.h" 
    
    extern Engine* pEng; 
    
    extern void StartVirtualEngineMatlab(); 
    extern void StopedVirtualEngineMatlab(); 
    
    BOOL APIENTRY DllMain(HMODULE hModule, 
             DWORD ul_reason_for_call, 
             LPVOID lpReserved 
           ) 
    { 
        switch (ul_reason_for_call) 
        { 
        case DLL_PROCESS_ATTACH: 
         StartVirtualEngineMatlab(); 
         break; 
        case DLL_THREAD_ATTACH: 
        case DLL_THREAD_DETACH: 
        case DLL_PROCESS_DETACH: 
         StopedVirtualEngineMatlab(); 
         break; 
        } 
        return TRUE; 
    } 
    
  3. 现在我在专注于一个测试项目(C#控制台应用程序)通过dll-wraper调用一个m文件。

    test.cs中

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Runtime.InteropServices; 
    
    namespace Test 
    { 
        class Program 
        { 
         [DllImport("dllwrap.dll", CallingConvention = CallingConvention.Cdecl)] 
         public static extern bool TestDll(); 
         [DllImport("dllwrap.dll", CallingConvention = CallingConvention.Cdecl)] 
         public static extern void MyFigure(); 
    
           static void Main(string[] args) 
           { 
            bool res = TestDll(); 
            if (res == false) 
             return; 
    
            MyFigure(); 
           } 
          } 
         } 
    

测试项目正在运行,做的工作,但有一个问题。 Matlab引擎在意外的时间崩溃。它可能会在开始或一段时间后崩溃。我甚至试图在engOpen(NULL)函数后立即停止突破点,但崩溃似乎不取决于我的休息。

我使用Visual Studio 2013,Matlab 2015a 32位。 请帮助建议。 谢谢。

+0

好的,所以你在你的代码中有一个错误。没有[testcase](http://stackoverflow.com/help/mcve),我们无能为力,除了建议您启动调试器并有步骤地执行程序外,我们无能为力。 –

回答

0

好吧,我发现了这个问题。 我只是删除行:

StopedVirtualEngineMatlab(); 

从dllmain.cpp

case DLL_PROCESS_DETACH: 
    StopedVirtualEngineMatlab(); 
    break; 
} 

,并把它作为外部funtion从Test.cs.的代码结束叫它

现在它工作完美。

但我仍然不明白为什么DLL_PROCESS_DETACH案例被调用...?