2015-10-18 126 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案例被調用...?