C++与matlab混合编程——C++调用MATLAB函数
笔者最近在从事一个MFC相关的项目,要求将用Matlab实现的算法通过应用MFC制作成一个小应用。其中有一部分内容需要求一个多元函数的最值。通过网络,我找到了两个C++优化库,dlib与MIDACO_Project ,可是这两个库中的优化函数的应用方式无法融入MFC编程框架,因此想到应用matlab与C++混合编程来实现相关计算。在网络上查了很多资料使问题得到了解决,下面对之前所查资料的内容做一番总结。
一、编译matlab函数
在matlab命令行输入窗口中输入“mex -setup”命令,打开对mex的配置选项,根据自己电脑上的配置,会显示出matlab自带的lcc-win32编译器和其它C编译器。我电脑是32位的,matlab版本为R2014a,C编译器为Visual studio2013的编译器。如下图所示,已经显示了我电脑上的两种编译器,在此可用鼠标点击选择“Microsoft Visual C++ 2013 Professional (c)”选项,有的版本的matlab会提示在命令行中输入字符来进行选择。有两种情况是matlab中无法显示其它的编译器选项:1、如果matlab先于visual studio安装的话,输入“mex -setup”命令,matlab里面会没法显示visual studio编译器,很简单的解决方法就是重新装一次visual studio保证其在matlab之后安装到电脑上;2、当前matlab版本无法支持电脑上的编译器,比如:matlab2014版本的就无法支持VS2015。在这个网站上有各个版本的matlab对编译器的支持情况,根据网站内的说明来下载对应的编译器。
接下来就要在matlab中创建需要被编译的函数了,很多网站内的例子都是一些很简单的函数,比如:两个数的求和,害得我一度认为只能够将一些较为简单的函数进行编译。我所写的函数如下图所示,其中的内容较为复杂,应用到了matlab中的@关键字来获取函数,并且在objrmse函数中还调用了很多其它的函数,将这个函数所调用的所有m文件放到当前目录下。
在命令行输入窗口中输入“mcc -W cpplib:WPCtriForTwo -T link:lib WPCtriForTwo.m”,其中前一个WPCtriForTwo是生成的库名,可以自己指定,WPCtriForTwo.m为需要被编译的,matlab函数文件。稍等一会,就可以完成对函数的编译,并且在当前目录中生成很多编译后的文件,需要用到的文件有三个:后缀名分别为:WPCtriForTwo.h,WPCtriForTwo.dll,WPCtriForTwo.lib。将这三个文件复制到项目中来,其中后缀名为dll的文件要放入MFC项目的debug目录中,后缀名为h的文件需要添加到项目中去,通过右击项目选择“添加”->“现有项”,从文件管理器中选择该文件放入项目中。由于在项目中会应用到很多从matlab编译过来的函数,我项目中建立一个文件夹matlabFunctionLib来放置编译生成的lib文件,并且将WPCtriForTwo.lib文件放进去。
二、配置MFC项目
将matlab程序编译为C++程序后,还需要很多matlab所提供的C++库的支持,这些库及其相应的头文件都放在了MATLBA的安装目录下的extern目录中。考虑到并不是每台电脑上都安装有matlab,因此我选择将这些内容复制到MFC项目中,通过相对路径的方式对这些内容进行引用。将“matlab安装目录/extern”目录中的include目录和lib目录一并复制到MFC项目中,如图内红框所示。
接下来设置项目对上述内容(包括通过编译生成的和从matlab中复制过来的)的引用。
右击打开项目的属性窗口,选中VC++目录选项,我们需要修改其中的包含目录和库目录两部分的内容,如下图所示。在"包含目录"中应用相对路径语法(注意:在VS中相对的是后缀名为vcxproj文件的路径)添加之前从matlab中复制加入的include目录,即添加一条“../include”信息。在"库目录"中添加之前从matlab中复制过来的lib目录中的相关库文件的目录,由于所设置的MFC项目为32位的,所以需要添加包含32位库的目录,因此编辑添加“..lib\win32\microsoft”。
选中“链接器”->“常规”->"附加库目录",在其中添加matlabFunctionLib目录的相对位置,这样项目编译时就可以找到所matlab函数编译所生成的库文件。
最后,在“链接器”->“输入”->"附加依赖项"中,输入如下内容:
mclmcrrt.lib
libmx.lib
libmat.lib
libeng.lib
WPCtriForTwo.lib
其中WPCtriForTwo.lib为编译生成的lib文件,其余的几个为matlab中所带的lib文件。这样就完成了混合编程的VS配置工作。
三、C++对所编译的matlab函数进行调用
在需要调用函数的文件中添加包含,对于我的项目就是#include “WPCtriForTwo.h”。可以参考这一篇博客中的例子来学习如何调用matlab函数。