-1

I have a mission to call Matlab functions from C++ poject. I know there are several ways to do that, I prefer to use it through Matlab Engine.

  1. I have several m-files work perfect in Matlab enviroment.

    mymat.m

    function myfig()
        figure;
    end
    
  2. I made a dll-wrapper in C++ to connect the m-files with 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. Now I am in focus on a Test project (C# Console Application) to call a m-files through dll-wraper.

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

The Test project is running and doing the job, but there is a problem. A Matlab Engine crashes in unexpected time. It may crash at the begining or after a while. I even tried to stop on breaking point right after the engOpen(NULL) function, but the crashing is seems not depending on my break.

I use Visual Studio 2013, Matlab 2015a 32bit. Please help in advise. Thanks.

Vugar
  • 99
  • 1
  • 5
  • Okay, so you have a bug in your code. There's nothing we can do to help you without a [testcase](http://stackoverflow.com/help/mcve), beyond suggesting you fire up your debugger and step through the program methodically. – Lightness Races in Orbit Oct 18 '15 at 12:52

1 Answers1

0

Ok, I found the problem. I just removed the line:

StopedVirtualEngineMatlab();

from dllmain.cpp

case DLL_PROCESS_DETACH:
    StopedVirtualEngineMatlab();
    break;
}

and put it as external funtion to call it from the end of the code of Test.cs.

Now it works perfect.

But still I don't understand why the DLL_PROCESS_DETACH case is invoked...?

Vugar
  • 99
  • 1
  • 5