1、Visual C+与Matlab的 联合使用,北京工业大学机电学院 张轩,为什么需要联合使用,遇到这样的情况您怎么办?使用Visual C+开发应用程序时需要: 进行矩阵求和、相乘、分解等运算; 求特征值和特征向量; 解偏微分方程; 进行线性规划或二次规划计算; ,自己编程?,周期长! 效率低! 不可靠!,使用Matlab,关于Matlab,基于矩阵运算的专业科学计算程序包; 大量高效、稳定的数学函数和算法; 包罗万象的专业数学工具箱; 简单易用的M语言; 直观快捷的图形处理; ,Visual C+与Matlab的互补性,Matlab 的缺点: 不能灵活开发Windows应用程序; 只能在Ma
2、tlab运行环境中执行; 运算速度较慢; Visual C+与Matlab的互补性,程序主体 Visual C+,计算模块 Matlab,怎样联合使用,方法1:在VC程序中使用Matlab C/C+数学函数库。 方法2:将Matlab的M文件翻译成C/C+语言,加入到VC程序中使用。 方法3:将Matlab的M文件编译成可执行文件,在VC程序中调用。,方法4:在VC程序中调用Matlab COM 对象。 此技术较为艰深,普通用户不易掌握。 方法5:在VC程序中调用Matlab计算引擎。此方法则需要Matlab程序的支持。前三种情况较为实用。 本文仅对前三种情况进行介绍。,方法1、2、3 的核心
3、内容,动态链接库 Matlab编译器MCC,动态链接库的概念,动态链接库是一可执行文件,其内部包含可被其它应用程序调用的函数。 动态链接库本身并不属于调用它的应用程序,而只是为其提供一个函数接口。 应用程序对库的链接过程是在程序运行中实现的,而非编译阶段。,动态链接库的构成和使用,一个动态链接库一般包括三部分内容 动态链接库文件(后缀为dll); 动态链接库输入文件(后缀为lib); 头文件(后缀为h/hpp)。,例如 libmatlb.dlllibmatlb.liblibmatlb.hpp,在VC程序中使用动态链接库有两种方式显式载入:需要执行装载函数。隐式载入:程序运行时自动装载。,Mat
4、lab编译器的功能,将M文件翻译成C/C+文件; 将M文件转化为C/C+文件并生成动态链接库或独立可执行文件; 将M文件转化为C文件并生成Mex文件; 将M文件转化为C文件并生成Simulink S函数。 ,Matlab编译器的使用格式,mcc -options fun fun2 . mexfile1 . mlibfile1 .options:编译器参数; fun fun2:要转换的M文件; mexfile1 .:要链接的Mex文件; mlibfile1 .:要链接的动态链接库输入文件。,Matlab C/C+数学函数库,Matlab C/C+数学函数库的概念 是一系列动态链接库的集合; 包含
5、400多个C/C+语言版本的Matlab数学函数; Matlab C/C+数学函数库的组成:,使用Matlab C/C+数学函数库,在Matlab中设置; 在Visual Studio中设置; 在应用程序中设置。,Matlab M文件的翻译,使用MCC可以将M文件转换为C/C+文件。 例如: 将myfun.m翻译成C代码: mcc -t -L C myfun 将myfun.m翻译成C+代码: mcc -t -L Cpp myfun,翻译后的函数,M函数fun对应的C/C+函数: InitializeModule_fun 模块初始化函数; TerminateModule_fun 模块注销函数;
6、mlfFun(在C+中为fun) fun的普通函数接口; mlxFun fun的feval版本的函数接口; Mfun fun的实际执行函数。 根据M函数的类型,可能还会产生以下函数: mlfVFun(在C+中为VFun) fun的无返回值版本的函数; mlfNFun(在C+中为Nfun) fun的指定输出参数个数版本的函数;,需要注意的事,Mablab编译器只能翻译M函数文件,而不支持M脚本文件; 编译后M文件中的条件语句中的persistent和global将不起作用; 当M文件中使用了对象的引用时,运行时可能会产生内存错误; 如果用户指定的文件中使用了其它M文件,并且在Matlab目录中存
7、在这些文件的同名文件,则编译器自动使用Matlab目录中的文件; ,Matlab M文件的编译,mcc -options fun fun2 . mexfile1 . mlibfile1 .,包装函数,针对不同目标文件(独立可执行文件、动态链接库文件和Mex文件)的附加接口函数。 例如:Fun.m Windows控制台程序:main函数; 动态链接库文件:FunInitialize函数和FunTerminate函数; 用W选项来控制。,将myfun.m,翻译为C代码并生成Mex文件: mcc -x myfun 翻译为C代码并生成独立可执行文件: mcc -m myfun 翻译为C+代码并生成独立
8、可执行文件: mcc -p myfun,Matlab Add-in插件,让Visual Studio自动地调用Matlab编译器完成所有的工作。 在Matlab中设置。 在Visual Studio中激活。,Matlab Add-in插件文件类型,C-MEX DLL 由C文件生成Mex文件; M-MEX DLL 由M文件生成Mex文件; Windows Console EXE 由M文件生成独立可执行的Windows控制台程序; Shared M-DLL 由M文件生成动态链接库文件; Simulink C S-Function 生成C语言版本的Simulink S函数。,Matlab Add-i
9、n插件选项,是否使用Matlab图形库; 是否产生主函数(包装函数); 生成C代码还是C+代码; 生成测试版程序还是正式版程序。,示例:二次规划程序,在VC程序中使用Matlab二次规划程序。 考虑求解以下问题:,操作过程,操作过程分为两步: 步骤一: 由M文件生成二次规划动态链接库。 步骤二: 在应用程序中使用二次规划动态链接库。 下面详细介绍,步骤一,使用Matlab Add-in向导建立工程QpLib; 采用如下选项打开文件: 文件ToolboxOptimquadprog.m Shared M-DLL; 使用Matlab图形库; 产生主函数; 使用C语言; 生成测试版程序。 编译生成Qp
10、Lib.dll和QpLib.lib文件。,步骤二(1),将QpLib.dll文件拷贝到系统目录或应用程序目录; 将QpLib.lib文件添加到调用二次规划函数的工程中; 在StdAfx.h中添加: #include “matlab.hpp“ #include “QpLib.h“,步骤二(2),添加初始化和注销二次规划动态链接库的代码: QpLibInitialize ( ); QpLibTerminate ( ); 一般将以上函数添加在以下消息响应函数中: OnInitialUpdate OnDestroy,步骤二(3),调用二次规划函数mlfQuadprog。 函数格式: mxArray *
11、 mlfQuadprog ( mxArray * * fval, mxArray * * exitflag, mxArray * * output, mxArray * * lambda, mxArray * H, mxArray * f, mxArray * A, mxArray * B, mxArray * Aeq, mxArray * Beq, mxArray * lb, mxArray * ub, mxArray * X0, mxArray * options, .),参数说明,H、f、A、B、Aeq、Beq、lb、ub对应:,X0为迭代初始值; 其它参数用于说明程序的运行细节; 返回值为最优解。,结果比较,应用程序运行结果:,Matlab程序运行结果:x =0.81.2,示例二,线性规划问题(由彭细荣提供),结果比较,使用Matlab求解器得到结果:,使用以前的Fortran程序得到结果:,满足约束要求。,不满足约束要求。,总结,本文简明地阐述了Visual C+和Matlab 联合使用的几种方法; 以二次规划程序为例,详细说明了将复杂M文件编译为动态链接库文件并在应用程序中使用的过程; Visual C+与Matlab联合使用的内容非常丰富,本文仅仅涉及皮毛,希望以此引起读者兴趣进行深入研究。,感谢各位 请予批评指正,谢谢!,