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 [email protected] */ /* 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; }