У меня есть миссия для вызова функций Matlab из C ++ poject. Я знаю, что есть несколько способов сделать это, я предпочитаю использовать это через Matlab Engine.
У меня есть несколько m-файлов, которые отлично работают в среде Matlab.
mymat.m
function myfig()
figure;
end
Я сделал dll-оболочку в C ++ для соединения 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;
}
Сейчас я нахожусь в фокусе на тестовом проекте (C # Console Application) для вызова m-файлов через 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();
}
}
}
Тестовый проект выполняется и выполняет свою работу, но есть проблема. Двигатель Matlab падает в неожиданное время. Это может произойти сбой в начале или через некоторое время. Я даже пытался остановиться на точке разрыва сразу после функции engOpen (NULL), но сбой, похоже, не зависит от моего перерыва.
Я использую Visual Studio 2013, Matlab 2015a 32bit.
Пожалуйста, помогите, посоветуйте.
Благодарю.
Хорошо, я нашел проблему.
Я только что удалил строку:
StopedVirtualEngineMatlab();
из dllmain.cpp
case DLL_PROCESS_DETACH:
StopedVirtualEngineMatlab();
break;
}
и поместите его как внешнюю функцию, чтобы вызвать его из конца кода Test.cs.
Теперь это работает отлично.
Но все же я не понимаю, почему вызывается случай DLL_PROCESS_DETACH …?
Других решений пока нет …