一般情况下,我们都是在MATLAB命令行下编译MEX文件,所用命令为:
>>mex Filename.c
但因MEX文件是以C/C++语言为主编写的程序,只不不过在MEX文件中添加了接口函数mexFunction,且该函数可与C/C++函数相一致。因此,可在VisualC++的IDE环境中编译MEX文件。这种方法将极大地方便编程者利用VisualC++ ClassWizard创建类和维护类,并利用VisualC++的项目管理进行项目管理。由于此种方法编写的MEX文件是在VisualC++的IDE环境中编译,因此,其调试方法与一般VC工程基本一致。
本节以“MyDLL”工程为例,阐述在VisualC++的IDE环境中编写和编译MATLAB MEX文件。
(1)修改mex.h
该文件在%MATLAB7%extern\include目录中,打开该文件,找到mexFunction函数申明,利用VC中的关键字“__declspec(dllexport)”,申明该函数为导出函数,并将文件另存为“mex_VC.h”。
/////////////////////原 MEX.h文件
void mexFunction(
int nlhs, /* number of expected outputs */
mxArray *plhs[], /* array of pointers to output arguments */
int nrhs, /* number of inputs */
const mxArray *prhs[] /* array of pointers to input arguments */
);
/////////////////////修改并另存为mex_VC.h
__declspec(dllexport)void mexFunction(
int nlhs, /* number of expected outputs */
mxArray *plhs[], /* array of pointers to output arguments */
int nrhs, /* number of inputs */
const mxArray *prhs[] /* array of pointers to input arguments */
);
(2)创建MFC AppWizard(dll)工程MyDll
运行VisualC++并单击File->New,打开Project对话框来创建各种VC工程,选取MFC Appwizard(dll)(图1-1,其它程序基本相同)。在loctation编辑框中输入欲创建工程的保存路径,在Project name编辑框中输入工程名如“MyDll”,单击OK进入下一步工程设置对话框,选中Regular DLL with MFC Statically Linked,单击Finish完成MyDll工程创建。
图1-1 MyDll工程创建
(3)设置系统选项
•设定头文件和库文件路径
菜单Tools->Options->Directories
Include files:添加%MATLAB7%extern\include
Include files:添加%MICROSOFT VISUALSTUDIO%VC98\MFC\SRC
Library files:添加%MATLAB7%extern\include
•设置编译连接选项
菜单Project->Settings
C/C++->Preprocessor definitions: 添加MATLAB_MEX_FILE
Link->Object/Library modules: 添加libmat.lib libmex.lib libmx.lib
General->Microsoft Foundation Classes: Use MFC in a Static Library
(4)编写DLL主程序
•在MyDll.h中添加头文件:
#include "mex_vc.h"
•在MyDll.cpp中添加头文件:
#include "stdafx.h"
•编写mexFunction函数
在MyDll.cpp文件最后中找到:CMyDllApp theApp;
在其后编写用户C函数和mexFuntion接口函数如下:
/////////////////////////////////用户C函数,**注:不在MyDll.h中进行函数申明
double OutPut(int n, double *rP)
{
int i; double *sum,sum0;
FILE *fp1;
sum=new double[1];//////////////////内存在管理机制为Cpp机制
if((fp1=fopen("OutPut1.txt","w"))==NULL){printf(" Can't open OutPutfile\n");exit(0);}
*sum=0.0;
fprintf(fp1,"Input %d Data is:",n);
for(i=0;i<n;i++){*sum=*sum+rP[i];fprintf(fp1," %7.2lf ",rP[i]);}
fprintf(fp1,"\nsum= %7.2lf \n",*sum);
fclose(fp1);
sum0=*sum;
delete sum;//////////内存在管理机制为Cpp机制
return sum0; /////// Cpp程序返回计算值
}
//////////////////////////////接口函数,**注:不在MyDll.h中进行函数申明
void mexFunction(
int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)///////////////////////////////////////////////////注:mexFunction要与mex_vc.h中一致,分行写
{int i;
double *rP,*lP,sum;
mxArray *lP0;
////////////////// 由 prhs[] 中取得MATLAB输入数据
rP=new double[nrhs]; //////////内存在管理机制为Cpp机制
for(i=0;i<nrhs;i++)rP[i]=mxGetScalar(prhs[i]);
///////////////// 调用Cpp程序
sum=OutPut(nrhs,rP);
//////////////// 进行数据类型转换,并存入 plhs[] 返回MATLAB
nlhs=nrhs;
plhs[0]=mxCreateDoubleMATrix(1,nlhs,mxREAL);
lP0=mxCreateDoubleMATrix(1,nlhs,mxREAL);
lP= new double[nlhs];
for(i=0;i<nlhs;i++)lP[i]=i*sum;
for(i=0;i<nlhs;i++)*(mxGetPr(lP0)+i)=*(lP+i);
plhs[0]=mxDuplicateArray(lP0); //使用内存数据拷贝函数mxDuplicateArray()
mxDestroyArray(lP0); ///////////内存在管理机制为MATLAB机制
delete rP;
delete lP;
}
////////////////////////结束
在VisualC++中编译得得动态链接子程序MyDll.dll,并在MATLAB命令行中调用。
>> clear all
>> Mydll(1,2,4,5,6,7)
ans =
0 25 50 75 100 125
同时,由于用户Cpp程序中执行了文件输出,在当前目录下生成“OutPut1.txt”文件,输出结果为:
Input 6 Data is: 1.00 2.00 4.00 1.00 6.00 7.00
sum= 21.00