Matlab 转换为VC++程序
一、 将MATLAB程序或函数打包为可独立运行的exe程序
1. 首先安装支持MATLAB 生成程序运行的动态链接库,路径:
D:\\MATLAB704\oolbox\\compiler\\deploy\\win32\\MCRInstaller.exe
2. 写好.m 程序,一般为函数,可以有输入输出参数
3. 在MATLAB里运行mcc -mv *.m
4. 运行exe程序即可得到结果。
5. 可在命令行中输入参数
二、 在VC++中调用MATLAB计算引擎
1. 将MATLAB注册为COM服务器
在WINDOWS下运行Matlab/regserver
2. 将engine.h 所在的目录加入编译器对头文件的搜索路径上,一般是:$MATLAB\\extern\\include, 把引擎函数库所在的目录加入搜索路径,一般是:
3. 把需要的函数库文件加入到编译所需的额外库文件参数中,文件名为:libeng.lib; libmx.lib; libmat.lib 等
4. 定义引擎变量,并且初始化
Engine* m_ep=NULL;//fj
if(!(m_ep=engOpen(\"\\0\")))
{
AfxMessageBox(\"Can't start MATLAB Engine!\");
return NULL;
}
//hide the command window
engSetVisible(m_ep,0);
5. 构造输入输出参数
mxArray *mxImage=NULL,*mxResult=NULL;
mxImage=mxCreateNumericMatrix(m_nImageWidth,m_nImageHeight,mxUINT16_CLASS,mxREAL);
memcpy((short*)mxGetPr(mxImage),(short*)m_pImageBuffer,m_nBuffSize);
engPutVariable(m_ep,\"image\
6. 构造MATLAB命令
//engEvalString(m_ep,\"figure;\");
//engEvalString(m_ep,\"imshow(image,[]);\");
//Evaluate the function of time
CString szStrel;
szStrel.Format (\"strcElement=strel('square',%d);\
engEvalString(m_ep,szStrel);
engEvalString(m_ep,\"result=imopen(image,strcElement);\");
engEvalString(m_ep,\"result=imclose(result,strcElement);\");
//plot the result
//engEvalString(m_ep,\"figure;\");
//engEvalString(m_ep,\"imshow(result,[]);\");
7. 接收输出结果
mxResult=mxCreateNumericMatrix(m_nImageWidth,m_nImageHeight,mxUINT16_CLASS,mxREAL);
mxResult=engGetVariable(m_ep,\"result\");
memcpy((short*)pMorphImage->m_pImageBuffer,(short*)mxGetPr(mxResult),m_nBuffSize);
8. 销毁MATLAB环境中使用的内存变量
//destroy the array
mxDestroyArray(mxImage);
mxDestroyArray(mxResult);
if(ep!=NULL)
engClose(ep);
三、 在VC++中调用MATLAB生成的动态链接库
1. 安装VC++编译器
在Matlab环境下, 输入 mbuild –setup 根据指示配置C++编译器
2. 在MATLAB环境中编译MATLAB函数
mcc –w cpplib: ***.lib -T link: lib ***.m ***.m
生成的和必须复制到VC程序当前目录下的文件有:***.h ***.lib ***.dll 和 ***.ctf
3. 在VC环境调用生成的动态链接库
(a) 初始化应用程序和库(经实验此段必须放在APP的InitInstance()函数中)
if(!mclInitializeApplication(NULL,0))
{
AfxMessageBox(_T(\"Could not initialize the application\"));
return FALSE;
}
else
;//AfxMessageBox(_T(\"Successfully initialize the application\"));
if(!LibBraExrInitialize())
{
AfxMessageBox(_T(\"Could not initialize the library\"));
return FALSE;
}
else
;//AfxMessageBox(_T(\"Successfully initialize the library\"));
(b) 初始化输入输出参数
//定义matlab可以识别的矩阵作为输入和输出
mwArray mwImage(m_nImageWidth,m_nImageHeight, mxINT16_CLASS, mxREAL);
mwImage.SetData (m_pImageBuffer,m_nImageWidth * m_nImageHeight);
int nThreshold[1]={0};
mwArray mwThreshold(1,1,mxUINT8_CLASS,mxREAL);
mwThreshold.SetData (nThreshold,1);
(c) 调用MATLAB函数并获得输出结果
DY_FUN_OTSU(1,mwThreshold,mwImage);
mwThreshold.GetData (nThreshold,1);
(d) 销毁MATLAB使用的环境变量
LibBraExrTerminate();
mclTerminateApplication();
四、 在VC++中调用MATLAB生成的COM组件
1. 安装VC++编译器
在Matlab环境下, 输入 mbuild –setup 根据指示配置C++编译器
2. 在MATLAB环境中编译MATLAB函数
使用dotnettool:创建新工程; 加入M程序; 编译工程; 打包和发布产生的COM组件
产生的DLL文件需要复制到当前程序目录下,如需发布,需要用***.exe程序解压,并执行install.bat
3. 在VC环境调用生成的动态链接库
(a) 导入DLL(在stdafx.h文件中)
#import \"EdgeExtraction_1_0.dll\" raw_interfaces_only
using namespace EdgeExtraction;
(b) 初始化和启动COM
CoInitialize(NULL); //initialize COM library
hresult=CLSIDFromProgID(OLESTR(\"EdgeExtraction.EdgeExtractionclass.1_0\"), &clsid); //retrieve CLSID of component
IEdgeExtractionclass *t;
hresult=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(IEdgeExtractionclass),(LPVOID *) &t);
if(FAILED(hresult))
{
AfxMessageBox(\"COM 启动失败!\");
return NULL;
}
(c) 定义输入输出变量
VARIANT input, output; //定义输入输出变量
VariantInit(&input);
VariantInit(&output);
//VariantInit(&output1);
input.vt= VT_I2 |VT_ARRAY;//声明输入的类型为VT_ARRAY,Array中的元素为short型
output.vt=VT_I2 |VT_ARRAY; //声明输出的类型为VT_ARRAY,Array中的元素为short型
//output.vt=VT_R8;
//output1.vt=VT_R8;
SAFEARRAYBOUND abound[2];
abound[0].cElements=m_nImageHeight;//第一维元素的个数
abound[0].lLbound=0; //第一维矩阵索引的下界
abound[1].cElements=m_nImageWidth;//第二维元素的个数
abound[1].lLbound =0;//第二维矩阵索引的下界
input.parray=SafeArrayCreate(VT_I2,2,abound);//该函数新建一个SafeArray,并把这个SafeArray的描述符的指针传给x.parray。
input.parray->pvData=pEdgeImage->m_pImageBuffer;
output.parray=SafeArrayCreate(VT_I2,2,abound);//该函数新建一个SafeArray,并把这个SafeArray的描述符的指针传给x.parray。
(d) 调用MATLAB函数
t->fj_FUN_EdgeExtraction (1, &output, input); //call method
(e) 获得输出结果
int HUGEP* pDest;
SafeArrayAccessData(output.parray, (void HUGEP**)&pDest);
// double totalLeft=output.dblVal ;
// double totalRight=output1.dblVal ;
memcpy(pEdgeImage->m_pImageBuffer, pDest, pEdgeImage->m_nBuffSize); // Copy into array
(f) 销毁MATLAB使用的环境变量
SafeArrayUnaccessData(output.parray);
//SafeArrayDestroy(output.parray); // destroy the array.
SafeArrayUnaccessData(input.parray);
//SafeArrayDestroy(input.parray); // destroy the array.
t->Release();
CoUninitialize(); //Unintialize the COM library
因篇幅问题不能全部显示,请点此查看更多更全内容