前言

该文档是刚毕业时做项目时用到的一些VC MATLAB混编的内容,供大家分享,有什么问题请大家批评指正。

VC MATLAB混编主要有两种方式:

第一种是运用MATLAB引擎,该方法的优点是在转成VC代码的时候只需要使用固定函数,然后将MATLAB代码完全复制,最后将VC和MATLAB的变量转换接口写好就可以了。缺点是需要安装整个MATLAB,依赖于MATLAB的自启动,而且程序运行效率较差。

第二种是应用MATLAB自带编译器,将函数编译成DLL和LIB文件,供VC程序调用。该方法优点是VC程序可以直接调用生成库文件里的函数,只需将VC程序里的变量转换成MATLAB函数需要的变量类型即可,而且程序运行效率较好。缺点不便于调试。

1. MATLAB引擎

1.1. 在64位win7操作系统下使用MATLAB2012b引擎的配置

1.1.1添加环境变量

Path变量中添加C:\Program Files\MATLAB\R2012b\bin\win64,如图1-1到图1-5所示。注意:添加完之后一定要重启计算机。

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(1)

图1-1 添加环境变量-1

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(2)

图1-2 添加环境变量-2

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(3)

图1-3 添加环境变量-3

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(4)

图1-4 添加环境变量-4

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(5)

图1-5 添加环境变量5

1.1.2 X64平台配置

在VS中需要添加MATLAB引擎环境的工程中设置成x64平台。进入“配置管理器”,增加x64平台,如图1-6到1-8所示。

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(6)

图1-6 X64平台配置-1

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(7)

图1-7 X64平台配置-2

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(8)

图1-8 X64平台配置-3

1.1.3 添加头文件和库文件

到项目属性中的C 目录中:

包含目录增加:C:\Program Files\MATLAB\R2012b\extern\include

库目录增加:C:\Program Files\MATLAB\R2012b\extern\lib\win64\microsoft

步骤如图1-9到图1-13所示。

最后添加上添加使用MATLAB引擎和函数需要的库文件和头文件:

#include “mat.h”

#include “engine.h”

#progma comment(lib,”libmx.lib”)

#progma comment(lib,”libmat.lib”)

#progma comment(lib,”libeng.lib”)

如图1-14所示

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(9)

图1-9 添加头文件和库文件-1

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(10)

图1-10 添加头文件和库文件-2

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(11)

图1-11 添加头文件和库文件-3

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(12)

图1-12 添加头文件和库文件-4

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(13)

图1-13 添加头文件和库文件-5

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(14)

图1-14 添加头文件和库文件-6

1.2. 使用MATLAB引擎VC与MATLAB变量转换说明

1.2.1 启动MATLAB引擎

在VC中使用MATLAB引擎首先要启动MATLAB引擎,代码如下:

Engine* ep; //定义MATLAB引擎指针。

If (!(ep=engOpen(NULL))) //测试是否启动MATLAB引擎成功。

{

AfxMessageBox(“Can’t start Matlab engine”);

}

1.2.2 写MATLAB函数命令

在VC使用MATLAB引擎中,写MATLAB语句非常简单,例如写一句MATLAB语句

“Figure,imshow(I)”,在VC中只要写成“engEvalString(ep,”Figure,imshow(I);”);”。

当MATLAB语句较长的时候或者有FOR循环或者IF语句的时候,可以将MATLAB代码写在一个engEvalString函数里,用“\”换行。举例如下:

MATLAB代码:

for i=1:5

for j=1:5

I(i,j)=1;

end

end

VC代码写成:

engEvalString(ep,”for i=1:5;\

for j=1:5;\

I(i,j)=1;\

end;\

end”);

1.2.3 VC与MATLAB混编举例

Void Detect(IN BYTE* pHBlob,BYTE* pLBlob,OUT BYTE* pBlob)

{

int iWidth=300;

int iHeight=300;

//定义MATLAB函数要使用的三个变量

mxArray* mxpHBlob=NULL;

mxArray* mxpLBlob=NULL;

mxArray* mxpBlob=NULL;

//给MATLAB输入两个变量分配空间

mxpHBlob=mxCreateNumericMatrix(iWidth,iHeight,,mxUINT8_CLASS,mxREAL);

mxpLBlob=mxCreateNumericMatrix(iWidth,iHeight,,mxUINT8_CLASS,mxREAL);

//将VC输入的变量地址拷贝给MATLAB输入变量

memcpy((void*)mxGetPr(mxpHBlob),(void*)pHBlob,iWidth*iHeight);

memcpy((void*)mxGetPr(mxpLBlob),(void*)pLBlob,iWidth*iHeight);

//将MATLAB输入变量传递到MATLAB中

engPutVariable(ep,”HBlob”,mxpHBlob);

engPutVariable(ep,”LBlob”,mxpLBlob);

//执行MATLAB函数

engEvalString(ep,”Blob=ImgRestruction(HBlob,LBlob);”);

//获得MATLAB函数输出变量

mxpBlob=engGetVariable(ep,”Blob”);

//将将MATLAB函数输出变量传递给VC函数输出变量

memcpy((void*)pBlob,(void*)mxGetPr(mxpBlob),iWidth*iHeight);

//销毁MATLAB变量矩阵空间

mxDestroyArray(mxpHBlob);

mxDestroyArray(mxpLBlob);

mxDestroyArray(mxpBlob);

return;

}

注意:自己写的MATLAB函数一定要放在..\R2012b\bin的目录下。

2. Matlab生成动态库

2.1. MATLAB生成动态库步骤

点击MATLAB Compiler,提示如图2-1所示,新输入一个工程名,类型选择C 共享库。第一次使用matlab生成动态库要安装编译器,如图2-2所示,在matlab中的Common Window窗口中输入mbuild –setup,然后提示选择一个编译器,依据自己需要选择,在项目里我们选择2。然后再MATLAB右端Build选项里点击Add files,选择需要编译的m文件,点击按钮进行编译,如图2-3、2-4所示。最后会在..My Document\Matlab\文件夹下生成一个m文件的文件夹,将其中生成的.lib、.dll、.h文件(如图2-5所示)拷贝到需要调用MATLAB动态库函数的VC工程目录下,即完成Matlab生成动态库的步骤。

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(15)

图2-1 MATLAB生成动态库-1

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(16)

图2-2 MATLAB生成动态库-2

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(17)

图2-3 MATLAB生成动态库-3

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(18)

图2-4 MATLAB生成动态库-4

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(19)

图2-5 MATLAB生成动态库-5

2.2. VC与MATLAB生成动态库函数混编方法

2.2.1 使用MATLAB生成动态库的配置

首先安装matlab运行时,在matlab的command window中输入mcrinstaller即可找到MCR的位置,点击安装即可。

在VC 目录下包含目录增加:C:\Program Files\MATLAB\R2012b\extern\include,

C:\Program Files\MATLAB\R2012b\extern\include\win64

库目录增加:C:\Program Files\MATLAB\R2012b\extern\lib\win64\microsoft(如图2-6到2-8所示)

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(20)

图2-6 使用MATLAB生成动态库配置-1

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(21)

图2-7 使用MATLAB生成动态库配置-2

matlab代码自动生成verilog代码(VCMATLAB混编技术文档)(22)

图2-8 使用MATLAB生成动态库配置-3

在链接器中输入添加附加依赖项mclmcrrt.lib mclmcr.lib Reconstruction.lib

预编译头stdafx.h中加入

#include ” mclmcrrt.h”

#include “mclcppclass.h”

#include “Reconstruction.h”头文件

然后初始化应用,初始化库函数(例如库文件名称为Restruction),代码如下:

If(!mclInitializeApplication(NULL,0))

{

AfxMessage(“Could not initialize the application!”);

}

If(!lRestructionInitialize())

{

AfxMessage(“Could not initialize the Restruction!”);

}

2.2.2 在没有安装MATLAB机器上的配置

由于MATLAB过于庞大,且安装费时,占用内存,所以一般不用在机器上安装整个MATLAB客户端,只需要安装MCR就能用VC调用MATLAB生成的动态库。安装方法见2.2.1。

在VC 目录下包含目录增加:

C:\Program Files\MATLAB\MATLAB Compiler Runtime\v80\extern\include

C:\Program Files\MATLAB\ MATLAB Compiler Runtime\v80\extern\include\win64

库目录增加:

C:\Program Files\MATLAB\ MATLAB Compiler Runtime\v80\\extern\lib\win64\microsoft

其他的配置见2.2.1。

2.2.3 VC MATLAB混编举例

例1

void Function(IN BYTE* pHBlob,BYTE* pLBlob,OUT BYTE* pBlob)

{

int iWid=300;

int iHei=300;

//定义MATLAB函数要使用的变量

mwArray* mwpHBlob;

mwArray* mwpLBlob;

mwArray* mwpBlob;

//为变量分配空间

mwpHBlob=new mwArray(iWid,iHei,mxUINT8_CLASS,mxReal);

mwpLBlob=new mwArray(iWid,iHei,mxUINT8_CLASS,mxReal);

mwpBlob=new mwArray(iWid,iHei,mxUINT8_CLASS,mxReal);

//将VC输入变量的值传给MATLAB输入变量

mwpHBlob.SetData(pHBlob,iWid*iHei);

mwpLBlob.SetData(pLBlob,iWid*iHei);

//执行MATLAB函数,函数第一个参数为输出变量值的个数

Reconstrction(1, mwpBlob, mwpHBlob, mwpLBlob);

//将MATLAB输出变量值传递给VC函数输出变量值

mwpBlob.GetData(pHBlob,iWid*iHei);

//销毁内存

delete mwpHBlob;

delete mwpLBlob;

delete mwpBlob;

return;

}

例2

CString strFrontPath=CString(“F:\\正面训练数据路径\\”);

mwArray * G_MWTrainDataFrontPath;

mwArray * G_MWRefGridDataFront;

mwArray * G_MWSubFrontRefImg;

G_MWTrainDataFrontPath=new mwArray(strFrontPath);

const char* fields[]={"V","meanV"};

G_MWRefGridDataFront=new mwArray(10,20,2,fields);

G_MWSubFrontRefImg=new mwArray(1000,2000,mxUINT8_CLASS,mxREAL);

mwArray V1(30000,50,mxDOUBLE_CLASS);

mwArray meanV1(1,30000,mxDOUBLE_CLASS);

for (int i=1;i<=10;i )

{

for (int j=1;j<=20;j )

{

(*G_MWRefGridDataFront)(fields[0],i,j)=V1;

(*G_MWRefGridDataFront)(fields[1],i,j)=meanV1;

}

}

loadMat(2,*G_MWRefGridDataFront,*G_MWSubFrontRefImg,*G_MWTrainDataFrontPath);

,