Vc调用matlab导出的dll,实现vc与matlab混合编程
写这篇博客的目的就是想把前段时间的工作交接下,让后来人接手这个项目的人迅速的入门。文章虽短,在项目初期可是搜刮了很多资料花了不少的时间。
为了与win7兼容,matlab应该安装2010a或2010b。Matlab7导出的dll在win7下的vc2010中不兼容。
1:首先为matlab选择编译器
在命名行窗口输入:mex-setup按照提示选择vc2010
2:选择builder
输入:mbuilder-setup同样选择vc2010
3:将使用matlab写成的代码封装成函数,确认无错后开始生成dll。
在命令行输入:mcc-Wcpplib:h_single-Tlink:libh_single.m
其中h_single是要导出的dll名称,h_single.m是matlab源文件。
不同版本的matlab生成dll的时间不一样,不知道我使用的matlab2012a为什么这么慢。
如果一切顺利,那么在.m文件目录下将会产生.lib,.dll,.h,.cpp,.ctf(matlab2010好像不再生成.ctf文件)等几个文件。我们需要使用.lib,dll,.h文件。
dll生成后,剩下的就是在vc中调用了。这跟使用其他dll是一样的。首先要包含dll头文件,除了要将本次生成的.lib文件填入:链接器-》输入内。还需要加入mclmcr.lib和mclmcrrt.lib。最后将dll文件放在可执行文件目录下。matlab2010好像不再生成.ctf文件,因此不需要将ctf文件放在当前目录下,而在matlab7中却需要。
这些都只是准备工作,包含了头文件才能在vc内使用。传入matlab函数的数据是有一定格式的。因此需要将数据准备下,准备好之后传给matlab计算函数。至于传入的数据格式,可以参照我写过的代码,很简单。我也做了详尽的注释。
上面只是把整个过程简单的介绍一遍,如果有其他问题可以参考我的其他博文。包括具体编译器的设置,出现过的错误及解决方案。所有这些都在vc与matlab混合编程目录下http://blog.csdn.net/ithzhang/article/category/1120011
示例代码,注意传给dll导出函数的参数的类型:
#include"stdafx.h"
#include"myh_single.h"
#include"h_single.h"
/************************************************************************/
/* single_cal函数。单回路水平排列。 */
/* BY: ithzhang ithzhang@foxmail.com */
/* date: 2012年4月11日 11:32 */
/* modify date:2012年4月12日19:47 改正matlab 生成的dll库无法多次被调用的bug*/
/* */
/* current:电流,p:3*2数组, 坐标 */
/* delta:步长,left:坐标系左起始点,right:坐标系右结束点, xy:传出,: */
/* 综合磁场强度数组。x:传出:水平磁场强度数组,y:垂直磁场强度数组。 */
/* 三数组长度均为:(right-left)/delta +1 */
/* */
/************************************************************************/
bool h_single_cal(double current,double coordinate[3][2],double delta,
double left,double right,double Height,double *(&xy),double *(&x),double *(&y))
{
static bool IsInitialzied=false;
/************************************************************************/
/* 初始化h_single库,仅能初始化一次,否则将会出现各种错误 初始化时间很长 */
/************************************************************************/
if(IsInitialzied==false)
{
if(!h_singleInitialize())
return false;
IsInitialzied=true;
}
/************************************************************************/
/* 定义mwArray类型的各个变量,传入matlab导出的h_single函数。 */
/************************************************************************/
mwArray ii (1,1,mxDOUBLE_CLASS);
mwArray p (3,2,mxDOUBLE_CLASS);
mwArray step (1,1,mxDOUBLE_CLASS);
mwArray s1 (1,1,mxDOUBLE_CLASS);
mwArray s2 (1,1,mxDOUBLE_CLASS);
mwArray H (1,1,mxDOUBLE_CLASS);
int num = (right-left) / delta;
num++;//不要忘了加1哦。
mwArray B_m(1,num,mxDOUBLE_CLASS);
mwArray B_x(1,num,mxDOUBLE_CLASS);
mwArray B_y(1,num,mxDOUBLE_CLASS);
ii(1,1) = current;
step(1,1) = delta;
s1(1,1) = left;
s2(1,1) = right;
H(1,1) = Height;
for(int i = 0;i < 3; i++)
{
for(int j = 0;j < 2; j++)
{
p(i + 1,j + 1) = coordinate[i][j];
}
}
/************************************************************************/
/* 调用matlab导出的h_single函数。h_single( 传出参数个数,传出参数,各个传入参数) */
/************************************************************************/
h_single(3,B_m,B_x,B_y,ii,p,step,s1,s2,H);
/************************************************************************/
/* 为传入指针申请内存空间,存储从h_single返回的结果。注意xy,x,y传入时是引用类型的指针*/
/* 在外部使用后,要注意释放这里申请的堆空间,否则将会导致内存泄露。 */
/************************************************************************/
xy = new double[num];
x=new double[num];
y=new double [num];
/************************************************************************/
/* 从MxArray类型的返回值中得到数据。 */
/************************************************************************/
B_m.GetData(xy,num);
B_x.GetData(x,num);
B_y.GetData(y,num);
/************************************************************************/
/* 执行成功返回true。 */
/************************************************************************/
return true;
}