目前我正在尝试直接在Visual Studio中调用MATLAB,但它似乎无法正常工作。
为清楚起见,以下面的演示案例为例,即使用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;
}
更多信息:
答案 0 :(得分:1)
对于Visual Studio 2010。
如果您使用的是Matlab 64,则需要将Visual Studio配置为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
。
代码的输出是
答案 1 :(得分:1)
这是我尝试的一个简单示例:
#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项目来编译它,we can do this直接来自MATLAB:
>> mbuild test_engine.cpp -llibeng -llibmx
在R2014a及以上,我们也可以使用:
>> mex -client engine test_engine.cpp
(假设您已经运行mex -setup
和mbuild -setup
来选择正确的C ++编译器,或者在R2014a中选择mex -setup C++
和mex -setup C++ -client MBUILD
。
这是程序的输出(我用VS2013运行R2014a x64):
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
这是how to在Visual Studio中编译上面的例子。
首先创建一个新的空“Win32控制台应用程序”项目
由于我们正在使用MATLAB x64,我们需要调整项目配置以生成64位二进制文件。从“Build”菜单中,选择“Configuration Manager”。从下拉菜单中选择<New>
以创建新的平台配置,选择x64
并接受。
添加上一个示例test_engine.cpp
下一步是告诉VC ++编译器/链接器在哪里找到MATLAB头文件和库。我们可以通过设置项目属性来完成此任务。
更好的方法是创建一个单独的property sheet,可以从多个项目中重复使用,而无需一遍又一遍地重复相同的设置。因此,创建如下所示的MATLAB_Engine.props
属性表,并将其添加到项目中(打开“Property Manager”面板,然后单击“添加现有属性表”按钮)。
最后构建解决方案并运行它( 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>
(适用于64位Windows上的MATLAB R2014a。如果将MATLAB安装到其他位置,请调整路径)
预期输出:
提示:如果您反复测试引擎程序,那么每次运行新的MATLAB进程都会在后台打开和关闭。为了在开发过程中简化操作,您可以启动一个正常的MATLAB会话,并执行下面的命令,告诉它像自动化服务器一样。这样,所有引擎程序都将在同一会话中运行,该会话仍保持打开状态。
>> enableservice('AutomationServer',true);
MATLAB documentation明确指出Engine库不是thread-safe(对于MEX-API和MAT-API也是如此)。在Windows系统中,独立Engine程序通过COM接口与外部MATLAB进程通信,而在Linux / Mac系统上使用pipes作为IPC机制。
因此,如果您创建多线程应用程序,请确保只有一个线程访问引擎应用程序。
注意:仅适用于Windows,还有另一个功能engOpenSingleUse
。它与engOpen
的不同之处在于它创建了一个新的非共享MATLAB引擎会话。这样,您可以将多个线程连接到不同的会话(显然工作空间不共享,因为每个会话都有一个单独的地址空间)。