在VS2008中联合使用Matlab编程的技巧一 在VS中使用Matlab来处理矩阵主要有两种方法,一种是直接是VS中编程打开Matlab引擎,输入Matlab语句,另外一种就是将Matlab的m.文件编译生成dll文件,在VS中调用该dll文件。 一、在VS中调用matlab生成的dll文件 该实例是基于VS2008和matlab2009a所实现的。 1、Matlab中的设置 首先在Matlab里面新建一个M文件,主要代码为: function =gray_model_test_sonar3(a) %function =gray_model_test_sonar3(a1,a2,a3,a4) %a= ; a1= ; B= ; B = double(B); F= ; C=B'*B; D=pinv(C);%求C的伪逆 D = double(D); F = double(F); E=D*B'*F; G=(a(1)-E(2)/E(1))*exp(-4*E(1))+E(2)/E(1); T=(a(1)-E(2)/E(1))*exp(-3*E(1))+E(2)/E(1); M=G-T; end 该段代码为使用灰色模型进行预测的基础代码,重点在于Matlab程序必须要包含着functiong和end之间。 将m文件保存为sonar3.m,保存在D:\test文件件中,然后在Matlab的command window中键入:cd D:\test,在Matlab主窗口中将当前路径改为D:\test。 然后设置matlab编译库,以便能够生成动态dll文件供VS调用,在Matlab主窗口中键入: mbuild -setup 会出现: Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers /n? 在这里我选择的n,得到显示: Select a compiler: Lcc-win32 C 2.4.1 Microsoft Visual C++ 6.0 Microsoft Visual C++ .NET 2003 Microsoft Visual C++ 2005 SP1 Microsoft Visual C++ 2008 Express Microsoft Visual C++ 2008 SP1 None Compiler: 输入6,回车 The default location for Microsoft Visual C++ 2008 SP1 compilers is C:\Program Files\Microsoft Visual Studio 9.0, but that directory does not exist on this machine. Use C:\Program Files\Microsoft Visual Studio 9.0 anyway /n? y Please verify your choices: Compiler: Microsoft Visual C++ 2008 SP1 Location: C:\Program Files\Microsoft Visual Studio 9.0 Are these correct /n? y **************************************************************************** Warning: Applications/components generated using Microsoft Visual Studio 2008 require that the Microsoft Visual Studio 2008 run-time libraries be available on the computer used for deployment. To redistribute your applications/components, be sure that the deployment machine has these run-time libraries. **************************************************************************** Trying to update options file: C:\Users\Vivian\AppData\Roaming\MathWorks\MATLAB\R2009a\compopts.bat From template: D:\PROGRA~1\MATLAB\R2009a\bin\win32\mbuildopts\msvc90compp.bat Done . . . 当出现如上说明,就代表编译器设置完成,接下来使用.m文件生成.dll文件 在Matlab中,.m文件生成.dll文件的指令如下: mcc -W cpplib:myadd -T link:lib add.m -C 其中,myadd是需要生成的dll的文件名,即生成的文件名为myadd.dll,add.m是指明通过哪个.m文件生成dll文件的,myadd和add可以不一样。输入时注意参数的大小写与空格。 键 入上述命令后,经过1到2分钟的编译,Matlab会在Test文件夹下生成9个新的文件,其 中,myadd.ctf,myadd.h,myadd.lib,myadd.dll是在VS中需要用到的文件。到此,Matlab中的函数已经成功生成一 个动态链接库,可供VS调用了。 2、VS2008中的设置 打开VS2008,新建一个MFC基于对话框的工程,按如下操作方式进行设置: 工具|选项|项目和解决方案|VC++,在右边的“显示以下内容的目录”中选择“包含文件",添加:D:\Programme Files\Matlab\R2009a\extern\include(根据Matlab的实际安装目录进行设置);再选择“库目录”,添加:D:\Programme Files\Matlab\R2009a\extern\lib\win32\microsoft(根据Matlab的实际安装目录进行设置)。该设置只需设置一次,对以后所有工程都有效。 针对某一项目进行的设置:(不同的项目每次都要进行设置) 将上述在Matlab中生成的四个文件myadd.ctf,myadd.h,myadd.lib,myadd.dll 拷贝到项目文件夹中,选择项目|属性|配置属性|链接器|输入,在右边的“附加依赖项目”中,添加“mclmcrrt.lib myadd.lib”,其中myadd.lib即为Matlab生成的lib文件。 3、基本设置完成后即可进入编码 首先,必须将myadd.h包含进来,即在cpp文件的最前面部分添加#include "myadd.h",在该头文件中主要包含三个内容,是dll里面的一些函数的函数名,分别为: extern LIB_sonar3_C_API bool MW_CALL_CONV sonar3Initialize(void); //初始化函数,在调用matlab函数前必须使用 extern LIB_sonar3_C_API void MW_CALL_CONV sonar3Terminate(void); //结束函数,释放相关资源 extern LIB_sonar3_CPP_API void MW_CALL_CONV gray_model_test_sonar3(int nargout , mwArray M , const mwArray a); //直接使用的调用函数,第一个参数nargout指输出参数的个数,然后是输出参数,最后是输入参数。涉及到matlab中的一种数据类型mwArray,在VS中可以通过mwArray相应的成员函数将其中的变量提取出来,再进行相应的操作。 在VS中的代码如下: sonar3Initialize(); if (!sonar3Initialize()) { cout"初始化失败"endl; exit(1); } //在被调用的matlab程序中,一共有四个输入a1、a2、a3、a4,分别对应于声纳数据s1、s2、s4、s5 //声明四个1行1列的maArray变量 //声明四个1行1列的maArray变量,保存对应的四个数据 try { mwArray a(4,1,mxDOUBLE_CLASS); a(1,1)=s1; a(2,1)=s2; a(3,1)=s4; a(4,1)=s5; /*这种参数设置出现问题,输出结果恒为0,原因暂时不明 mwArray a1(1,1,mxUINT32_CLASS); a1.SetData(s1,1); mwArray a2(1,1,mxUINT32_CLASS); a2.SetData(s2,1); mwArray a3(1,1,mxUINT32_CLASS); a3.SetData(s4,1); mwArray a4(1,1,mxUINT32_CLASS); a4.SetData(s5,1); */ //声明一个y用于保存输出结果 mwArray y(1,1,mxUINT32_CLASS); //调用函数 gray_model_test_sonar3(1,y,a1,a2,a3,a4); //结果保存在y中,现在将y中的结果提取出来,保存到M中 y.GetData(M,1); cout"对于Sonar3的预测数据为:"Mendl; } //出现异常时的处理代码 catch(mwException e) { str.Format(_T("%s"),e.what()); cout"初始化失败123"endl; } sonar3Terminate(); 4、程序运行中的各种问题 (1) Microsoft C++ 异常: 内存位置 0x042cfbe8 处的 CFileException。 内存泄漏问题: 文件IO是经常出现异常的地方,你应该在进行IO操作的时候加入 TRY { IO操作 } CATCH(CFileException,e) //该代码是必须的 { 出现异常时的处理代码 } END_CATCH (2)当存在两个矩阵相乘时报错 : ??? Error using == mtimes Integer data types are not fully supported for this operation. At least one operand must be a scalar. 这时需要在matlab中奖待乘的矩阵进行强制转换为double型,如B=double(B),但如此转换可能出现内存不足的问题,完美解决方法还没有找到。 (3) matrix is singular to working precision 矩阵出现奇异,无法求逆,此时在matlab中使用pinv命令代替inv命令,pinv为求伪逆