远程计算_使用Matlab计算引擎
2015-06-13 00:06
495 查看
0 环境
win7 32bitvs2008
matlab r2013b
1 准备工作
确保vs与matlab均已正确安装添加环境变量
PATH:
D:\Program Files\MATLAB\R2013b\bin\win32,(我的matlab安装在
D:\Program Files\MATLAB\,如果不是这个路径则做相应修改,64bit系统路径最后则为win64,下同)
vs设置,工具 -> 选项 -> 项目和解决方案 -> VC++ 路径,Platform选择Win32,然后
Include files中添加
D:\Program Files\MATLAB\R2013b\extern\include
Library files中添加
D:\Program Files\MATLAB\R2013b\extern\lib\win32\microsoft
注意高版本的VS如2013已经将该设置迁移到项目属性中。
附加依赖项设置,项目属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项,编辑加入
libeng.lib。(也可直接在代码中加入
#pragma comment(lib, "libeng.lib")语句)
关于以上路径设置的说明
环境变量Path:指定系统搜索路径(此处用于查找
libeng.dll等dll文件),也可不设置而是将该路径下所有用到的dll文件拷贝到当前路径中
头文件路径:指定头文件的搜索路径(此处为
engine.h文件以及该文件中包含的其他头文件),也可不设置,但包含头文件时需要使用完整路径,这样头文件较多时会比较麻烦
库文件路径:指定库文件的搜索路径(此处为
libeng.lib文件),可以不设置,但
#pragma comment时需要使用lib文件的完整路径,或者将该文件拷贝到当前路径下
2 引擎函数介绍
下表列出了本文用到的所有引擎函数函数 | 说明 |
---|---|
engOpen | 启动matlab计算引擎(创建了一个matlab进程并建立联系) |
engClose | 关闭引擎(关闭创建的matlab进程) |
engSetVisible | 设置引擎窗口是否可见 |
engOutputBuffer | 设置引擎文本输出缓冲区(每次使用engEvalString执行新命令都会使缓冲区清空并填入新的结果),执行代码 engOutputBuffer(ep, NULL, 0)可停用缓冲区 |
engEvalString | 执行matlab命令 |
[函数原型]
Engine* engOpen(const char* startcmd)
[参数说明] 用于启动matlab的字符串命令,Windows中为
NULL
[返回值] 引擎指针
engClose
[函数原型]
int engClose(Engine* ep)
[参数说明] 引擎指针,即
engClose函数的返回值
[返回值] 0成功,1失败
engSetVisible
[函数原型]
int engSetVisible(Engine* ep, bool newVal)
[参数说明]
ep为引擎指针;
newVal为
true表示显示引擎窗口,
false表示隐藏引擎窗口
[返回值] 0成功,1失败
engOutputBuffer
[函数原型]
int engOutputBuffer(Engine* ep, char* buffer, int buflen)
[参数说明]
ep为引擎指针;
buffer为文本输出缓冲区指针;
buflen为缓冲区大小
[返回值] 0成功,1失败
engEvalString
[函数原型]
int engEvalString(Engine* ep, const char* string)
[参数说明]
ep为引擎指针;
string为要执行的命令文本
[返回值] 0成功,1失败
3 引擎使用
包括打开与设置引擎、执行命令、关闭引擎三个部分打开引擎并设置。包括打开引擎、设置不可见、设置输出缓冲区以及设置工作空间为当前路径,代码如下
// 打开并设置Matlab引擎 int MatlabOpen(Engine** ep, const char* sPath, char* sBuffer, int nBufLen) { // 启动matlab引擎 if (!(*ep = engOpen(NULL))) // 启动引擎 { return 1; // 启动失败 } // 设置 engSetVisible(*ep, false); // 设置窗口不可视 engOutputBuffer(*ep, sBuffer, nBufLen); // 设置Matlab输出缓冲区 // 修改工作路径 char sWorkPath[MAX_PATH]; sprintf_s(sWorkPath, MAX_PATH, "cd '%s'", sPath); engEvalString(*ep, sWorkPath); return 0; }
关闭引擎。代码如下
// 关闭Matlab引擎 int MatlabClose(Engine* ep) { return engClose(ep); }
执行命令。执行命令获取文本结果,如果有画图命令则将Figure保存为图片
// 执行Matlab命令 // 返回图片个数 int MatlabExec(Engine* ep, const char* mCmd) { int nFig = 0; // 图片个数 engOutputBuffer(ep, matbuf, MATBUFSIZE); // 恢复输出缓冲区 engEvalString(ep, mCmd); // 执行命令 engOutputBuffer(ep, matbuffig, MATBUFFIGSIZE); // 临时缓冲区,保存检测是否有Figure的结果 // 判断是否有figure并处理 engEvalString(ep, "isempty(findall(0,'Type','Figure'))"); if (strlen(matbuffig) > 13 && '0' == matbuffig[13]) // 有Figure { char savefig[100] = {0}; char gettype[20] = {0}; int i = 1; sprintf_s(gettype, 20, "get(1,'Type');"); engEvalString(ep, gettype); while(matbuffig[0] == 0) // 空 { // 将Figure保存为图片 sprintf_s(savefig, 100, "set(%d,'color','white');f=getframe(%d);imwrite(f.cdata,'figure%d.png');", i, i, i); engEvalString(ep, savefig); nFig++; // 下一个 sprintf_s(gettype, 20, "get(%d,'Type');", ++i); engEvalString(ep, gettype); } engEvalString(ep, "close all"); // 关闭所有Figure } return nFig; // 返回图片个数 }
4 示例
由于关于Matlab计算引擎的操作都要在同一个线程内执行,而项目需要在其他多个线程中执行matlab命令,因此考虑采用线程消息的方式实现。即在主线程中启用计算引擎,其他线程通过向主线程发送消息来请求计算,命令通过消息参数传递。完整代码如下#include <stdio.h> #include <tchar.h> #include <windows.h> #include "engine.h" #pragma comment(lib, "libeng.lib") #define WM_CALC WM_USER+200 // 请求计算消息 // 全局变量 #define MATBUFSIZE 10240 #define MATBUFFIGSIZE 256 char matbuf[MATBUFSIZE] = {0}; // Matlab输出缓冲区 char matbuffig[MATBUFFIGSIZE] = {0}; // 临时输出缓冲区 DWORD dwMainThreadId = 0; // 主线程ID // 函数声明 DWORD WINAPI ThreadTest(LPVOID lpParam); // 测试线程 int MatlabOpen(Engine** ep, const char* sPath, char* sBuffer, int nBufLen); int MatlabClose(Engine* ep); int MatlabExec(Engine* ep, const char* mCmd); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // 获取线程ID dwMainThreadId = GetCurrentThreadId(); // 启动matlab引擎 Engine* ep = NULL; // matlab引擎 char path[MAX_PATH]; // 当前路径 strcpy_s(path, MAX_PATH, __argv[0]); (_tcsrchr(path, '\\'))[1] = 0; // 只保留路径部分 if (MatlabOpen(&ep, path, matbuf, MATBUFSIZE)) { return 0; } // 创建测试线程 CreateThread(NULL, 0, ThreadTest, 0, 0, NULL); // 线程消息循环 MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); while(GetMessage(&msg, NULL, 0, 0)) { if (msg.message == WM_CALC) // 请求计算消息 { MatlabExec(ep, (char*)msg.wParam); // 执行matlab命令 } } // 关闭matlab引擎 MatlabClose(ep); return (int) msg.wParam; } // 测试线程 DWORD WINAPI ThreadTest(LPVOID lpParam) { Sleep(1000); PostThreadMessage(dwMainThreadId, WM_CALC, WPARAM("pi"), 0); // 输出pi Sleep(1000); PostThreadMessage(dwMainThreadId, WM_CALC, WPARAM("plot(sin(0:0.1:10))"), 0); // 画正弦曲线 Sleep(5000); PostThreadMessage(dwMainThreadId, WM_QUIT, 0, 0); // 退出程序 return 0; } // MatlabOpen、MatlabClose、MatlabExec三个函数的实现分别见3.1、3.2、3.3,此处不再列出 // ……
测试结果:
第一次计算后matbuf值为
"ans = 3.1416"
exe路径下生成文件
figure1.png,如下图
本文原文链接 /article/10927863.html
相关文章推荐
- 用OxyPlot在WPF中演示正演磁异常的变化规律
- 在64位系统上不能安装Matlab notebook的解决方案
- MATLAB中统计程序执行时间
- Matlab变量名的神奇问题
- 关于matlab SVM工具箱的问题
- matlab 学习资料收集
- Matlab拟合曲线之幂律分布
- Matlab与VC6联合编程备忘录
- MATLAB——scatter的简单应用
- matlab中“执行字符串”函数eval在不同情况下的用法(二)
- MATLAB中feval、class、'function_handle'、isa、strcmp的用法
- 分享快速双边滤波matlab程序
- MATLAB——axis
- MATLAB——PLOT绘图
- 统计相关系数(3)——Kendall Rank(肯德尔等级)相关系数及MATLAB实现
- matlab的inpolygon用法简单介绍
- 热迁移数据与matlab绘图
- ubuntu14.10下安装MATLAB-2013b
- 使用matlab计算DFT时需要注意的幅值对应问题
- 【MATLAB 从零到进阶】day2 矩阵 数组