• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

怎么在C++里面调用MATLAB - MorningChen

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

怎么在C++里面调用MATLAB

使用matlab engine的,比较好用,不过要求目标机器也装有matlab才行。具体的话,可以去找vaa4这个id,看他做过。

=====================

(hplonline)2009.11.10

》》目的:

1.实现快速结果验证
2.方便的矩阵运算
3.方便的绘图模块

》》环境:

VISTA+MATLAB2009a+VC6.0

》》资料:

以安装路径“E:\Program Files\MATLAB\R2009a\”为例

MATLAB外部支持文件夹:
E:\Program Files\MATLAB\R2009a\extern
matlab自带的c例程:
E:\Program Files\MATLAB\R2009a\extern\examples\eng_mat

engine.h的位置:
E:\Program Files\MATLAB\R2009a\extern\include

各种lib的位置:
E:\Program Files\MATLAB\R2009a\extern\lib\win32\microsoft

在matlab帮助中输入“C language”即可找到有关MATLAB Engine的一个页面。
从这个页面开始,学习各种关键词,
就能够找到一切你需要的资料。

使用MATLAB Engine一般用两套函数就可以了。
1.engXXXX,关于Engine本身的操作,包括打开/关闭,设置/取得变量,执行语句等等。
2.mxXXXX,关于数据类型mxArray的操作,与MATLAB交互的左右类型全部为mxArray。

》》一个搭建实例

先在VC6的tools->options->directories里添加相关目录

include files:
E:\Program Files\MATLAB\R2009a\extern\include

library files:
E:\Program Files\MATLAB\R2009a\extern\lib\win32\microsoft

做好这些后,如果我们环境一样,
下面的代码应该能够编通并且正常执行,
其中包含了常用的一些函数,
一般来说使用Engine的时候也就用这些了。

 

代码
#include <stdlib.h>
#include
<stdio.h>
#include
<string.h>

#include
"engine.h"
#include
"matrix.h"

#pragma comment(lib,"libeng.lib")
#pragma comment(lib,"libmx.lib")

int main()
{
Engine
*ep;
int i , j ;

//show how to open MATLAB engine
//for remote ones:
//engOpen( ADDRESS OF REMOTE SYSTEM ) ;

if (!(ep = engOpen("\0"))){
fprintf(stderr,
"\nCan\'t start MATLAB engine\n");
return EXIT_FAILURE;
}

//show how to create matrix
mxArray *Y = mxCreateDoubleMatrix(1 , 3 , mxREAL) ;

//show how to put data in matrix
double tmp[3] = {1.0 , 2.0 , 3.0} ;
memcpy(mxGetPr(Y) , tmp ,
sizeof(tmp)) ;

//show how to put variables in the Engine
engPutVariable(ep , "Y" , Y) ;

//show how to execute commands in MATLAB
engEvalString(ep, "X = ones(5,1) * Y");

//show how to get variables from the Engine
mxArray *X = engGetVariable(ep , "X") ;

//show how to manipulate dimensions
int dims[10] ;
int ndims ;
ndims
= mxGetNumberOfDimensions(X) ;
printf(
"total number of dimensions is %d\n" , ndims) ;
memcpy(dims , mxGetDimensions(X) , ndims
* sizeof(int)) ;
for ( i = 0 ; i < ndims ; i ++ ){
printf(
"dimension %d : %d\n" , i , dims[i]) ;
}
printf(
"\n") ;

//show how the data is stored in the memory
double *p = (double*)mxGetData(X) ;
for ( i = 0 ; i < dims[0] ; i ++ ){
for ( j = 0 ; j < dims[1] ; j ++ ){
printf(
"%8.2f" , p[j * dims[0] + i]) ;
}
printf(
"\n") ;
}

//---important, to release resources
mxDestroyArray(X) ;
mxDestroyArray(Y) ;

//show how to hide and unhide MATLAB command window
printf("type RETURN to hide the MATLAB command window...\n") ;
getchar() ;
engSetVisible(ep ,
false) ;
printf(
"type RETURN to unhide the MATLAB command window...\n") ;
getchar() ;
engSetVisible(ep ,
true) ;

printf(
"type RETURN to END this program...\n") ;
getchar() ;
//remembering to close it is important .
//but if you are debugging your programs ,
//annotate the following line will save you a lot of time ,
//for you needn\'t to restart the Engine .
engClose(ep) ;

//when your work is accomplished , type "exit" in MATLAB command window

return EXIT_SUCCESS;
}

 

》》某些问题

如果出现这个:

engdemo.obj : error LNK2001: unresolved external symbol _engClose
engdemo.obj : error LNK2001: unresolved external symbol _engSetVisible
engdemo.obj : error LNK2001: unresolved external symbol _mxDestroyArray
engdemo.obj : error LNK2001: unresolved external symbol _mxGetData
engdemo.obj : error LNK2001: unresolved external symbol _mxGetDimensions_730
engdemo.obj : error LNK2001: unresolved external symbol _mxGetNumberOfDimensions_730
engdemo.obj : error LNK2001: unresolved external symbol _engGetVariable
engdemo.obj : error LNK2001: unresolved external symbol _engEvalString
engdemo.obj : error LNK2001: unresolved external symbol _engPutVariable
engdemo.obj : error LNK2001: unresolved external symbol _mxGetPr
engdemo.obj : error LNK2001: unresolved external symbol _mxCreateDoubleMatrix_730
engdemo.obj : error LNK2001: unresolved external symbol _engOpen

其实就是lib没有添加好。

在代码中写上:
#pragma comment(lib,"libeng.lib")
#pragma comment(lib,"libmx.lib")
就可以了。

或者可以在工程的连接设置里面添加这两个库。
不过我倾向于前者,这样在发布源码的同时,
就尽最大可能地保证能够编译,
而不用其他人学习的时候再去设置。

当然,由于#pragma是由编译器自己决定的,
所以代码的可移植性存在一些问题。

如果还是报上面的错误,估计是没有将lib的路径添加对。
具体参考上面的那个实例,然后注意把路径换成自己机器上的。

》》小结

前几天围观了一个人用MATCOM混编,
发现确实很混。。。
比如调用rand的时候,直接就被MATLAB的rand给覆盖了。
因为他的头文件里面有类似
#define rand randM ?????
这样的东西,
于是在编译器接到代码之前,该代码已经被预处理替换了。
这样根本不会出现函数重复的编译或者连接错误。
这在某种意义上带来了一些隐患,影响调试。
(当时帮他看了半天才反映过来。。。)

使用MATLAB Engine的话,双方代码的隔离性很好。
由于使用字符串进行代码交互,开发效率可能会低一点。
另外在数据交互上比较麻烦一点,需要mxXXX系列的函数。

用MATCOM的时候甚至可以直接写出
mVar = CVar ;
这样的赋值。。。
由已经实现好的强大的类库来完成底层的转换。

from 青水河畔 hplonline


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi 根据字符串创建对象发布时间:2022-07-18
下一篇:
我学Delphi心得与笔记-------在控件上如何禁用Ctrl+V发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap