В настоящее время я пытаюсь вызвать MATLAB непосредственно в Visual Studio, но, похоже, он не работает.
Для ясности возьмем в качестве примера следующий демонстрационный пример, т.е. используйте MATLAB для вычисления 2+3
, Ожидается, что результат, т.е. ans = 5
, должны быть напечатаны в строке printf("%s\n", buf);
, который оказывается пустым. Кстати, движок MATLAB открыт (engOpen()
) успешно.
#include <stdio.h>
#include <thread>
#include "engine.h"
Engine *matlab;
void thread_func()
{
// set printing buffer
char buf[1001];
engOutputBuffer(matlab, buf, 1000);
// call MATLAB
engEvalString(matlab, "2+3");
printf("%s\n", buf); // if ok, should print "ans = 5" in the command window
}
int main()
{
// Open MATLAB engine
matlab = engOpen(NULL);
if (matlab == NULL){
printf("Error to open MATLAB engine!!!\n");
exit(-1);
}
// use "Engine *matlab" in this thread
std::thread another_thread(thread_func);
// wait the thread to finish
another_thread.join();
// Close MATLAB engine
engClose(matlab);
return 0;
}
Больше информации:
Вот простой пример, который я попробовал:
#include <cstdio>
#include "engine.h"
#define BUFSIZE 1000
int main()
{
// open connection
Engine *matlab = engOpen(NULL);
if (matlab == NULL) {
fprintf(stderr, "Error to open MATLAB engine\n");
return EXIT_FAILURE;
}
// output buffer
char buf[BUFSIZE+1];
buf[BUFSIZE] = '\0';
engOutputBuffer(matlab, buf, BUFSIZE);
// call MATLAB
engEvalString(matlab, "x = magic(5)");
printf("Output:\n%s\n", buf);
// close connection
engClose(matlab);
return EXIT_SUCCESS;
}
Вместо того, чтобы вручную создавать проект Visual Studio для его компиляции, мы можем это сделать прямо из MATLAB:
>> mbuild test_engine.cpp -llibeng -llibmx
в R2014a и выше мы также можем использовать:
>> mex -client engine test_engine.cpp
(при условии, что вы бежали mex -setup
а также mbuild -setup
выбрать правильный компилятор C ++, или mex -setup C++
а также mex -setup C++ -client MBUILD
в R2014a).
Вот вывод программы (я использую R2014a x64 с VS2013):
C:\> test_engine.exe
Output:
x =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Вот как скомпилируйте приведенный выше пример в Visual Studio.
Начните с создания нового пустого проекта «Win32 Console Application»
Поскольку мы работаем с MATLAB x64, нам нужно настроить конфигурацию проекта для генерации 64-битных двоичных файлов. В меню «Сборка» выберите «Диспетчер конфигурации». Из выпадающего меню выберите <New>
для создания новой конфигурации платформы выберите x64
и принять.
Добавьте исходный код из предыдущего примера test_engine.cpp
Следующий шаг — сообщить компилятору / компоновщику VC ++, где найти заголовки и библиотеки MATLAB. Мы могли бы сделать это, установив свойства проекта.
Лучше всего создать отдельный лист недвижимости это может быть повторно использовано из нескольких проектов без необходимости повторять одни и те же настройки снова и снова. Так что создайте MATLAB_Engine.props
список свойств, показанный ниже, и добавьте в него проект (откройте панель «Диспетчер свойств» и нажмите кнопку «Добавить существующий список свойств»).
Наконец, соберите решение и запустите его (Ctrl+F5)
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<LocalDebuggerEnvironment>PATH=C:\Program Files\MATLAB\R2014a\bin\win64;%PATH%$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>C:\Program Files\MATLAB\R2014a\extern\include;C:\Program Files\MATLAB\R2014a\extern\include\win64</AdditionalIncludeDirectories>
<PreprocessorDefinitions>IBMPC</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>C:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft</AdditionalLibraryDirectories>
<AdditionalDependencies>libmx.lib;libmex.lib;libmat.lib;libeng.lib;mclmcrrt.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
(это предназначено для MATLAB R2014a в 64-битной Windows. Настройте путь, если вы установили MATLAB в другое место)
Выход, как и ожидалось:
Совет: если вы тестируете программу движка несколько раз, то каждый раз при запуске новый процесс MATLAB открывается и закрывается в фоновом режиме. Чтобы упростить процесс разработки, вы можете запустить обычный сеанс MATLAB и выполнить приведенную ниже команду, чтобы он действовал как сервер автоматизации. Таким образом, все программы Engine будут работать в том же сеансе, который остается открытым.
>> enableservice('AutomationServer',true);
MATLAB документация прямо заявляет, что библиотека Engine не потокобезопасной (то же самое касается MEX-API и MAT-API). В системах Windows, автономный двигатель программы взаимодействуют с внешним процессом MATLAB через COM интерфейс, в то время как он использует трубы в системах Linux / Mac как IPC механизм.
Поэтому, если вы создаете многопоточные приложения, убедитесь, что только один поток обращается к приложению движка.
Примечание: только для Windows, есть другая функция engOpenSingleUse
, Отличается от engOpen
в том смысле, что он создает новый сеанс ядра MATLAB без общего доступа. Таким образом, вы можете иметь несколько потоков, каждый из которых подключен к отдельному сеансу (очевидно, что рабочее пространство не используется совместно, поскольку каждый сеанс имеет отдельное адресное пространство).
Для Visual Studio 2010.
Если вы используете Matlab 64, вам нужно настроить 64-битную визуальную студию.
Первый шаг:
включают engine.h
C/C++->General->Additional Include Directories
добавлять C:\Program Files\MATLAB\R2014a\extern\include
Шаг второй:
Linker->General->Additional Library Directories
добавлять C:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft
Шаг третий:
добавлять C:\Program Files\MATLAB\R2014a\bin\win64
в переменных среды.
Вывод вашего кода