-1

我的任务是从 C++ 项目中调用 Matlab 函数。我知道有几种方法可以做到这一点,我更喜欢通过 Matlab Engine 使用它。

  1. 我有几个 m 文件在 Matlab 环境中完美运行。

    我的

    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 文件。

    测试.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 位。请帮忙指教。谢谢。

4

1 回答 1

0

好的,我发现了问题。我刚刚删除了这一行:

StopedVirtualEngineMatlab();

从 dllmain.cpp

case DLL_PROCESS_DETACH:
    StopedVirtualEngineMatlab();
    break;
}

并将其作为外部函数从Test.cs代码的末尾调用。

现在它完美无缺。

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

于 2015-10-18T15:17:10.097 回答