作 者: gaxlin 标 题: VC++与MATLAB7.0以上版本连接方法 时 间: Sat Jan 27 21:23:05 2007 点 击: 167
VC++ MATLAB 7 连接 混合编程 。本文适合VC++与MATLAB7.0以上版本连接方法,有些难,但 慢慢按这步骤一步步做是能看懂的,要有耐心,我研究了2天才实现了.如果有什么疑问可以 留言. 所有调用MATLAB7 Compiler产生的共享库的程序都具有如下的大致结构: 1. 声明变量或者是函数作为输入变量; 2. 调用 mclInitalizeApplication函数,并测试是否成功,该函数设置了一个全局的MC R状态,并且构建MCR实例; 3. 对于每个库,调用一次<libraryname>Initalize函数,为库创建一个MCR实例; 4. 调用库中的函数,并处理其结果(这是程序的主要部分); 5. 为每个库调用一次<libraryname>Terminate函数,用于注销相联系的MCR; 6. 调用mclTerminateApplication函数,释放与全局MCR状态相联系的资源; 7. 清除变换,关闭文件等,然后退出。 根据MATLAB的帮助文档中提供的例子,利用如下文件进行练习: <matlabroot>/extern/examples/compiler/addmatrix.m <matlabroot>/extern/examples/compiler/multiplymatrix.m <matlabroot>/extern/examples/compiler/eigmatrix.m 实现步骤: 1) 先将这几个文件拷贝到当前目录下,然后利用mcc创建共享库,指令如下: mcc -B csharedlib:libmatrix addmatrix.m multiplymatrix.m eigmatrix.m –v 其中,操作参数 -B csharedlib 是一个绑定的操作,其等效指令为 -W lib:<libname> - T link:lib。 2)在VC中创建一个MFC工程(本人创建的为基于对话框的),环境设置根据如下帖子:ht tp://genial.yculblog.com/post.218721.html 指导进行。在本例子中,只需要在VC中进 行如下步骤: A. ToolsàOptionsàDirectoriesàShow directories for:Include filesà<matlab7r oot> \Extern\Include; B. ToolsàOptionsàDirectoriesàShow directories for:Library filesà<matlab7r oot> \Extern\Lib\Win32\Microsoft\msvc60; C. ProjectàSettingàC/C++àCategory:Code GenerationàUse run-time library:D ebug Multithread DLL; D. ProjectàSettingàLinkàCategory:InputàObject/library modules:mclmcrrt.l ib libmatrix.lib(mcc生成的共享库)。 3)拷贝MATLAB当前目录下刚才用mcc生成的libmatrix.h,libmatrix.dll,libmatrix.li b,以及libmatrix.ctf文件到VC当前工程目录下,并用ProjectàAdd to ProjectàFiles …将libmatrix.h加入到当前工程中。 4)在当前工程的对话框的头文件中加入#include "libmatrix.h" 与 #include "mclmcr. h"; 5)在BOOL CMatlab7dllDlg::OnInitDialog()中进行MATLAB库文件的初始化,在void CMa tlab7dllDlg::OnDestroy()中进行MATLAB库文件资源的释放,否则可能出现按钮只能够按 一次,第二次运行则出错的现象; 6)调用MATLAB产生的库文件中函数的处理函数定义在一个按钮的响应函数中,并且要注意 的是:如果一个mxArray变量需要重用的时候,必须用mxDestroyArray(out); out=0;即先 进行变量注销,再设置为空。 附上这几个主要函数如下: 1.BOOL CMatlab7dllDlg::OnInitDialog() { CDialog::OnInitDialog(); …………… // TODO: Add extra initialization here /* Call the mclInitializeApplication routine. Make sure that the applicatio n * was initialized properly by checking the return status. This initializat ion * has to be done before calling any MATLAB API's or MATLAB Compiler genera ted * shared library functions. */ if( !mclInitializeApplication(NULL,0) ) { AfxMessageBox( "Could not initialize the application."); exit(1); } /* Call the library intialization routine and make sure that the * library was initialized properly. */ if (!libmatrixInitialize()) { AfxMessageBox("Could not initialize the library."); exit(1); } return TRUE; // return TRUE unless you set the focus to a control }
2.void CMatlab7dllDlg::OnDestroy() { CDialog::OnDestroy(); /* Call the library termination routine */ libmatrixTerminate(); mclTerminateApplication(); }
3.void CMatlab7dllDlg::OnRUN() { CString str; mxArray *in1, *in2; /* Define input parameters */ mxArray *out = NULL;/* and output parameters to be passed to the library fu nctions */ double data[] = {1,2,3,4,5,6,7,8,9};
/* Create the input data */ in1 = mxCreateDoubleMatrix(3,3,mxREAL); in2 = mxCreateDoubleMatrix(3,3,mxREAL); memcpy(mxGetPr(in1), data, 9*sizeof(double)); memcpy(mxGetPr(in2), data, 9*sizeof(double)); /* Call the library function */ mlfAddmatrix(1, &out, in1, in2); /* Display the return value of the library function */ str="The value of added matrix is:\n"; str = str + Display(out); AfxMessageBox(str);
/* Destroy the return value since this varaible will be resued in * the next function call. Since we are going to reuse the variable, * we have to set it to NULL. Refer to MATLAB Compiler documentation * for more information on this. */ mxDestroyArray(out); out=0;
mlfMultiplymatrix(1, &out, in1, in2); str = "The value of the multiplied matrix is:\n"; str = str+Display(out); AfxMessageBox(str);
mxDestroyArray(out); out=0;
mlfEigmatrix(1, &out, in1); str = "The Eigen value of the first matrix is:\n"; str = str+Display(out); AfxMessageBox(str);
mxDestroyArray(out); out=0; /* Free the memory created */ mxDestroyArray(in1); in1=0; mxDestroyArray(in2); in2 = 0;
AfxMessageBox("OK, Finished!"); }
4.CString CMatlab7dllDlg::Display(const mxArray *in) { CString str, strout=" "; int i=0, j=0; /* loop index variables */ int r=0, c=0; /* variables to store the row and column length of the matrix */ double *data; /* variable to point to the double data stored within the mxA rray */ /* Get the size of the matrix */ r = mxGetM(in); c = mxGetN(in); /* Get a pointer to the double data in mxArray */ data = mxGetPr(in); /* Loop through the data and display the same in matrix format */ for( i = 0; i < c; i++ ){ for( j = 0; j < r; j++){ str.Format("%4.2f\t",data[i*c+j]); strout = strout+str; } strout = strout+"\n"; } strout = strout +"\n"; return strout; }
5.附m文件: 1)addmatrix.m function a = addmatrix(a1, a2) %ADDMATRIX Add two matrices % Copyright 2003 The MathWorks, Inc. a = a1 + a2;
2) multiplymatrix.m function m = multiplymatrix(a1, a2) %MULTIPLYMATRIX Multiplies two matrices % Copyright 2003 The MathWorks, Inc. m = a1*a2;
3) eigmatrix.m function e = eigmatrix(a1) %EIGMATRIX Returns the eigen value of the given matrix % Copyright 2003 The MathWorks, Inc. e = eig(a1); 发布方法: 在MATLAB7.0的TOOL目录下找到MCRInstaller.exe,在目标机器上点击运行MCRInstaller.e xe文件,安装好MCR之后,将<mcr_root>\runtime\win32加入到系统的环境变量path中去。 同时还要copy工程文件的可执行程序,共享库(DLL),共享库对应的.ctf文件,在VC++源程 序的DEBUG目录下。 |