寫在前面——這個(gè)是為了我個(gè)人便于查詢而把我在網(wǎng)上搜到的一些關(guān)于vc中調(diào)用MATLAB函數(shù)的文章放到一起,后面貼有原文鏈接(有的也是轉(zhuǎn)的)。第一個(gè)是MATLAB engine的,第二個(gè)是MATLAB+vc6產(chǎn)生DLL,第三個(gè)是MATLAB+vs2005也是產(chǎn)生DLL。 【轉(zhuǎn)】 vc調(diào)用matlab函數(shù) Matlab 是由Math Works 公司于1984 年推出的數(shù)值計(jì)算及圖形處理軟件,可以實(shí)現(xiàn)數(shù)值分析、優(yōu)化、統(tǒng)計(jì)、偏微分方程數(shù)值解、自動(dòng)控制、信號處理、圖像處理等若干領(lǐng)域的計(jì)算和圖形顯示功能。其中,控制系統(tǒng)工具箱的集成為設(shè)計(jì)和分析各種復(fù)雜的控制系統(tǒng)提供了有效的方法和途徑。 但是,由于Matlab開發(fā)平臺的局限性,在其上面開發(fā)的程序不能脫離Matlab運(yùn)行環(huán)境,因而在處理一些實(shí)際應(yīng)用問題時(shí)顯得靈活性不足,而VC++則在一定程度上能夠彌補(bǔ)這一漏洞,因此,現(xiàn)將二者結(jié)合共用,各獻(xiàn)其長,可以為科研工作和工程開發(fā)提供了更為強(qiáng)大的技術(shù)支持。 1、Matlab與VC混合編程的實(shí)現(xiàn)方法 Matlab作為控制系統(tǒng)設(shè)計(jì)的一種通用工具,它可以和VC方便的進(jìn)行連接。一般而言,Matlab與VC混合編程的實(shí)現(xiàn)方法主要有以下三種方法:(1)通過引擎(Engine),采用客戶機(jī)服務(wù)器的計(jì)算模式,通過Window的ActiveX通道和Matlab進(jìn)行連接。具體應(yīng)用時(shí),往往在VC中設(shè)計(jì)程序框架,以編譯的程序作為前端客戶機(jī);通過調(diào)用Matlab引擎在后臺實(shí)現(xiàn)與服務(wù)器的連接,實(shí)現(xiàn)動(dòng)態(tài)通信(2)應(yīng)用Matlab數(shù)學(xué)函數(shù)庫,Matlab中包含了內(nèi)容豐富的函數(shù)庫,而且還提供了與VC的數(shù)學(xué)函數(shù)接口,用戶可以方便的在VC的IDE(集成開發(fā)環(huán)境)中調(diào)用。(3)通過DLL實(shí)現(xiàn)VC與Matlab的混合編程。DLL是一個(gè)可執(zhí)行的二進(jìn)制文件。把很多通用的功能放在DLL中,可以供多個(gè)應(yīng)用程序調(diào)用,這樣可以很好的減少外部存儲空間的占有量,并實(shí)現(xiàn)代碼的共享[2]。在上述三種方法中,第一種方法對調(diào)用Matlab的工具箱很實(shí)用,所有在進(jìn)行控制系統(tǒng)的設(shè)計(jì)和分析時(shí),一般都是通過調(diào)用Matlab引擎(Engine)來實(shí)現(xiàn)的。本文主要介紹采用通過引擎(Engine)來實(shí)現(xiàn)VC與Matlab的混合編程。 2、MATLAB引擎簡介 Matlab引擎是Matlab提供的一系列程序的結(jié)合,它允許用戶在自己的應(yīng)用程序中對Matlab進(jìn)行調(diào)用,將Matlab作為一個(gè)操作引擎使用,使其在后臺運(yùn)行。一般Matlab 引擎采用客戶機(jī)/ 服務(wù)器(Client/ Sever) 計(jì)算方式,就是一種把應(yīng)用處理負(fù)載分布到客戶機(jī)和服務(wù)器上的一種計(jì)算模式,客戶機(jī)和服務(wù)器既可以是存在于同一臺計(jì)算機(jī),也可以通過網(wǎng)絡(luò)來實(shí)現(xiàn)信息共享。一般情況下,客戶機(jī)是運(yùn)行前端軟件的PC機(jī),并且知道如何與服務(wù)器通信,服務(wù)器與此相對應(yīng),是接收請求信息,并采取相應(yīng)行的機(jī)器。由于客戶機(jī)和服務(wù)器共同承擔(dān)處理負(fù)載,使系統(tǒng)總體性能大為提高。在實(shí)際應(yīng)用過程中,把VC的C語言或C + + 語言的程序作為前端客戶機(jī)程序,它從Matlab 引擎接收數(shù)據(jù)信息,并與引擎?zhèn)鬟f命令的數(shù)據(jù)信息。表1是幾種常用的Matlab引擎調(diào)用函數(shù)。 表1 Matlab引擎常用調(diào)用函數(shù) 通過Matlab引擎用戶可以完成以下任務(wù):首先,可以將Matlab作為一個(gè)功能強(qiáng)大的和可編程的數(shù)學(xué)函數(shù)庫,調(diào)用Matlab中的大量的數(shù)學(xué)計(jì)算函數(shù),完成復(fù)雜的計(jì)算任務(wù);其次,可以為一個(gè)特定的任務(wù)構(gòu)建一個(gè)完整的系統(tǒng),前臺的用戶界面用高級語言編寫,后臺的計(jì)算任務(wù)由Matlab引擎來完成;最后,用戶不但可以在本地計(jì)算機(jī)上調(diào)用Matlab引擎,而且還可以通過網(wǎng)絡(luò)調(diào)用其它計(jì)算機(jī)上的Matlab引擎,這樣可以很好的實(shí)現(xiàn)資源的共享和作業(yè)的分工合作。 3、Matlab引擎實(shí)現(xiàn)VC和Matlab混合編程的步驟 要想在VC集成環(huán)境下利用Matlab引擎實(shí)現(xiàn)VC和Matlab的混合編程, 一般需要經(jīng)過以下幾個(gè)必要的步驟: ?。?)Visual C++6.0 編譯環(huán)境的設(shè)置:通過菜單 Tools/ Options,打開Visual C++6.0設(shè)置屬性頁,進(jìn)入 Directorie頁面,在 Show Directories for下拉列表中選擇Include Files,添加路徑:D:\Matlab6p5\extern\include(在Matlab的安裝路徑下);再選擇下拉列表中的 Library Files,添加路徑:D:\Matlab6p5\extern\ lib\win32\Microsoft\msvc60(在Matlab的安裝路徑下)。編譯環(huán)境只需設(shè)置一次。 (2)添加庫文件: 通過菜單 Projects|settings,進(jìn)入 Link 頁面,在 Object/Library Modules 框中,添加庫文件名:libmx.lib 、libmat.lib 、libeng.lib。每個(gè)新的工程文件都要單獨(dú)添加庫文件。 ?。?)在使用 engine 函數(shù)的程序頭文件中包含如下兩個(gè)頭文件: #include "engine.h" #include <stdlib.h> ?。?)在應(yīng)用程序中添加調(diào)用Matlab引擎的程序代碼: { Engine *ep; if(!(ep=engOpen(" \0"))) //打開Matlab引擎,建立與本地Matlab的連接 { fprintf(stderr,"\n Can't start MATLAB engine\n"); exit(-1); } 以上步驟是對VC與Matlab混合編程的編譯環(huán)境進(jìn)行設(shè)置,在完成了以上基本步驟后就可以利用Matlab引擎庫函數(shù)engEvalString來調(diào)用Matlab的內(nèi)建函數(shù)了。 根據(jù)上面的方法,下面通過一個(gè)具體的實(shí)力來說明如何實(shí)現(xiàn)VC與Matlab混合編程、它們之間的數(shù)據(jù)通信以及VC環(huán)境下對Matlab命令的調(diào)用。 首先,利用VC++6.0的MFC建立一個(gè)單文檔結(jié)構(gòu)的應(yīng)用程序,加入一個(gè)菜單資源,為其映射相應(yīng)的功能函數(shù); 其次,根據(jù)Matlab引擎實(shí)現(xiàn)VC和Matlab的混合編程步驟(見第三部分)為程序設(shè)置相應(yīng)的編譯環(huán)境并添加連接庫函數(shù); 然后,調(diào)用Matlab的內(nèi)建函數(shù)和命令,主要編寫程序代碼如下: … static double Areal[6]={1,2,3,4,5,6}; mxArray *T=NULL,*a=NULL,*d=NULL; double time[10]={0,1,2,3,4,5,6,7,8,9}; T=mxCreateDoubleMatrix(1,10,mxREAL); memcpy((char*)mxGetPr(T),(char*)time,10*sizeof(double)); engPutVariable(ep,"T",T); engEvalString(ep,"D=.5.*(-9.8).*T.^5;"); engEvalString(ep,"plot(T,D);"); … 最后,添加頭文件:編譯運(yùn)行,就可以得到如(圖1)所示的結(jié)果。 圖1 調(diào)用Matlab引擎輸出結(jié)果 上面例子是VC和Matlab的混合編程的一個(gè)簡單應(yīng)用,在實(shí)際的數(shù)值計(jì)算,控制系統(tǒng)開發(fā)等工程應(yīng)用中,可以很好的利用VC和Matlab的混合編程技術(shù),從而簡化應(yīng)用程序的開發(fā)工作量。 5、結(jié)論 Matlab提供了強(qiáng)大的數(shù)學(xué)計(jì)算功能和豐富的工具箱, 使用VC和Matlab的混合編程, 可以發(fā)揮各自特長, 縮短工程應(yīng)用軟件的開發(fā)周期, 同時(shí)也提高了程序的運(yùn)行效率。其中,基于客戶機(jī)/服務(wù)器計(jì)算模式的Matlab引擎是實(shí)現(xiàn)VC與Matlab 混合編程的一種常用方法。通過對引擎調(diào)用與數(shù)據(jù)組織方式的面向?qū)ο蟮脑O(shè)計(jì),將數(shù)據(jù)組織透明化,極大地簡化了程序設(shè)計(jì)過程, 封裝了對Matlab 引擎的訪問和與Matlab 服務(wù)器進(jìn)行數(shù)據(jù)交換的細(xì)節(jié),為用戶提供了一個(gè)友好的編程接口環(huán)境。 http://hi.baidu.com/ysuwjl/blog/item/cb4fe68055d056c8bd3e1eb8.html 【轉(zhuǎn)】VC調(diào)用matlab中定義的.m文件中的函數(shù)的實(shí)例 -----這個(gè)寫得比較清楚 Matlab是一個(gè)強(qiáng)大的數(shù)學(xué)計(jì)算/仿真工具,其內(nèi)置了很多實(shí)用的現(xiàn)成的函數(shù),而且我們經(jīng)常也自己定義很多m函數(shù)。但在很多情況下,我們不得不使用VC編程。那么,如何在VC中利用matlab的資源呢?在這里我簡要的以一個(gè)簡單的例子來說明一下如果在VC中調(diào)用matlab中定義的.m文件。繁多的理論就不說了,簡明扼要的說一個(gè)實(shí)例。相信大家看過之后都會(huì)馬上學(xué)會(huì)的J 其中灰色底顯示的部分是需要我們手工輸入的部分。 步驟如下: ㈠當(dāng)然是先建立 matlab 的 m 文件。 這里為了簡單起見,我在matlab中定義了一個(gè)函數(shù),其m文件如下: function y = add_zh(a,b) y=a+b 保存為myfunct.m ㈡下面來對 matlab 編譯環(huán)境進(jìn)行設(shè)置。打開matlab,在命令行狀態(tài)下鍵入:mex-setup 然后出現(xiàn)如下提示: -------------------------------------------------------------------------------------- Select a compiler: [1] Borland C++Builder version 5.0 in C:\Program Files\Borland [2] Lcc C version 2.4 in F:\SOFT\SHARE\MATLAB65\sys\lcc [3] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio [0] None Compiler: -------------------------------------------------------------------------------------- 這里我們選擇’3’。(如果使用其他的編譯器比如BCB,那么就可以相應(yīng)的選擇’1’) 然后,繼續(xù)在命令行狀態(tài)下輸入: mbuild –setup -------------------------------------------------------------------------------------- Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers [y]/n? y Select a compiler: [1] Borland C++Builder version 5.0 in C:\Program Files\Borland [2] Lcc C version 2.4 in F:\SOFT\SHARE\MATLAB65\sys\lcc [3] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio [0] None Compiler: -------------------------------------------------------------------------------------- 這里需要幾步確認(rèn)。大家按情況操作即可。 ㈢對 VC 的編譯器環(huán)境進(jìn)行設(shè)置。在Tools-options-directory里面設(shè)置include和lib的路徑,分別添加一項(xiàng),指向matlab安裝目錄中的\extern\include和 \extern\lib ㈣這一步比較關(guān)鍵。在這一步中,將 matlab 中的 .m 文件轉(zhuǎn)換為 dll 。 在matlab命令行中輸入: mcc -t -h -L C -W lib:ppp -T link:lib myfunct.m 至此,可以發(fā)現(xiàn)在myfunct.m所在的目錄中產(chǎn)生了一大堆文件。我們只用其中3個(gè): ppp.h ppp.lib ppp.dll ㈤新建一個(gè) VC 工程 。這里取名為 mat 。為了簡單,我們在這里建立一個(gè)對話框來進(jìn)行演示。如下: 然后,將上面這3個(gè)文件拷貝到VC工程所在的目錄中,以便VC調(diào)用之。 ㈥進(jìn)行 VC 編程。 首先,在cpp文件中加入: #include “ppp.h” 然后,設(shè)置VC的鏈接庫。在project-settings-link下的object/library modules中加入: ppp.lib libmx.lib libmatlb.lib libmmfile.lib 至此,VC的編譯環(huán)境設(shè)置完畢。下面就是編程部分了。 ㈦編程部分的關(guān)鍵:接口和數(shù)據(jù)類型的轉(zhuǎn)換 先給出 VC 實(shí)現(xiàn)的源代碼: ------------------------------------------------------------------------ void CMatDlg::OnButton1() { // 在 matlab 中定義的 m 文件 :myfunct ,其功能是完成兩個(gè)數(shù)的相加操作。 CString str; UpdateData(true); pppInitialize(); // 為了調(diào)用 matlab 中的函數(shù),必須使用數(shù)組數(shù)據(jù)類型,并其后調(diào)用 matlab 函數(shù)將其轉(zhuǎn)化為矩陣格式( matlab 的基本數(shù)據(jù)類型是矩陣) static double x1[1]={1.0}; static double x2[1]={2.5}; double result; // 調(diào)用 matlab 創(chuàng)建 3 個(gè)矩陣 mxArray *A=mclGetUninitializedArray(); mxArray *B=mclGetUninitializedArray(); mxArray *C=mclGetUninitializedArray(); // 將 C 語言中的變量值賦給 matlab 中的矩陣 mlfAssign(&A,mlfDoubleMatrix(1,1,x1,NULL)); mlfAssign(&B,mlfDoubleMatrix(1,1,x2,NULL)); mlfAssign(&C,mlfMyfunct(A,B)); // 將 matlab 中的矩陣的指針傳遞給 C 語言中的指向 double 的指針 double * md=mxGetPr(C); result=md[0]; // 釋放這些矩陣 mxDestroyArray(A); mxDestroyArray(B); mxDestroyArray(C); str.Format ("It is : %f",result); ::AfxMessageBox(str); } ------------------------------------------------------------------------ 相信看到里面的注釋,我們就明白的差不多了。 VC 編程以實(shí)現(xiàn)對 matlab 函數(shù)的調(diào)用,例如 VC 中我們實(shí)現(xiàn)兩個(gè) double 型的相加,則需要做上述的編程:首先定義兩個(gè)數(shù)組并存入我們要進(jìn)行函數(shù)操作的數(shù)據(jù)(也就是所謂的實(shí)參);然后將這兩個(gè)數(shù)組轉(zhuǎn)換為 matlab 可以識別的矩陣;然后調(diào)用 m 文件中自定義的函數(shù),對矩陣進(jìn)行操作;最后將結(jié)果再轉(zhuǎn)回 VC 支持的數(shù)據(jù)格式: double * md=mxGetPr(C); result=md[0]; 至此,經(jīng) matlab 函數(shù)處理過的數(shù)據(jù)已經(jīng)存入了 VC 中的 result 變量。 mlfAssign(&C,mlfMyfunct(A,B)); 大家可以看出來,在進(jìn)行調(diào)用的時(shí)候,我們使用的是 m 文件的文件名 myfunct ,而不是 m 文件中定義的 add_zh(a,b) http://www./edaiqingwa/archive/2009/08/01/20741.html 【轉(zhuǎn)】vs調(diào)用通過dll調(diào)用matlab程序 ----這個(gè)也講的很詳細(xì),而且是直接用vs2005舉例的,不錯(cuò) 程序中使用MATLAB編譯產(chǎn)生的DLL (VS2005, MATLAB7.5, mwArray) 實(shí)驗(yàn)內(nèi)容:把一個(gè)簡單的m代碼編譯成C++接口的DLL,然后在C++程序中調(diào)用。為了簡單起見,這里的C++程序是一個(gè)Win32 Console程序,而不是Windows圖形界面的程序,不過不妨礙我們的討論。 下面是這個(gè)例子用到的m代碼。它定義了一個(gè)名為myadd2的函數(shù): CODE: function [y,z] = myadd2(a, b) % dummy function, just to demonstrate the idea y = a+b; z = a+2*b; end 首先把這個(gè)函數(shù)編譯成C++接口的DLL。為此,我們需要先設(shè)置MATLAB編譯器。具體做法是在MATLAB命令行執(zhí)行“mbuild -setup”。然后用下面這行命令把myadd2函數(shù)編譯成一個(gè)C++接口的DLL: CODE: mcc -W cpplib:libmyadd2 -T link:lib myadd2 結(jié)果,我們將會(huì)得到包含libmyadd2.dll,libmyadd2.ctf,libmyadd2.h,libmyadd2.lib等在內(nèi)的一些文件。接下來我們只需要這四個(gè)文件。請注意:在MATLAB R2007b之前,這些文件都會(huì)在和編譯的m代碼所在的目錄中,而在MATLAB R2007b,缺省情況下這些文件會(huì)在Documents and Settings中用戶的My Documents目錄中。 然后在VS2005中創(chuàng)建一個(gè)Win32 Console的VC++工程,我在測試時(shí)取名為testmyadd2_r2007b。把以上四個(gè)(全部文件)文件拷貝到VC++工程的源代碼所在目錄。 接下來設(shè)置VC++,讓它能找到MATLAB接口函數(shù)的定義及連接庫函數(shù)??梢杂袃煞N設(shè)置方式:一種是改VS2005中關(guān)于VC++的設(shè)置,這樣的好處是每個(gè)新的工程都能自動(dòng)獲得這個(gè)設(shè)定;而另一種是只改當(dāng)前工程的設(shè)置,也就是設(shè)置只對該工程有效。這里用后一種方式。 在VS2005中打開工程testmyadd2_r2007b,選擇菜單“Project-->Properties,在出來的對話框上,把MATLAB提供的include路徑加到VC++的頭文件搜索路徑。如圖所示: D:\MATLAB7\extern\include 然后把相應(yīng)的lib所在目錄加到linker的額外搜索路徑上。如圖所示: D:\MATLAB7\extern\lib\win32\microsoft\msvc71 接下來,告訴VC++,我們的這個(gè)程序需要連接到另外兩個(gè)額外的庫函數(shù):libmyadd2.lib和mclmcrrt.lib。中間用空格隔開。如圖所示: 最后則是程序代碼。這個(gè)程序只有一個(gè)main函數(shù) CODE: #include "stdafx.h" #include #include "mclmcr.h" #include "mclcppclass.h" #include "libmyadd2.h" int _tmain(int argc, _TCHAR* argv[]) { std::cout << "Hello world!" << std::endl; if( !mclInitializeApplication(NULL,0) ) { std::cout << "Could not initialize the application!" << std::endl; return -1; } // initialize lib if( !libmyadd2Initialize()) { std::cout << "Could not initialize libmyadd2!" << std::endl; return -1; } try { // declare and initialize a mwArray a(2, 2, mxDOUBLE_CLASS); double *aData; aData = new double[4]; int i; for( i=0; i<4; ++i) { aData[i] = 1.0*i; } // print output std::cout << "a = " << std::endl; std::cout << aData[0] << ", " << aData[1] << std::endl; std::cout << aData[2] << ", " << aData[3] << std::endl; a.SetData(aData, 4); // declare and initialize b mwArray b(2, 2, mxDOUBLE_CLASS); b(1,1) = 11.; b(1,2) = 12.; b(2,1) = 21.; b(2,2) = 22.; mwArray y(2, 2, mxDOUBLE_CLASS); mwArray z(2, 2, mxDOUBLE_CLASS); // call the function myadd2(2, y, z, a, b); // copy data from mwArray to C++ objects // allocate outputs double *yData, *zData; yData = new double[4]; if( yData == NULL ) { std::cout << "Failed to allocate memory for yData!" << std::endl; return -1; } zData = new double[4]; if( zData == NULL ) { std::cout << "Failed to allocate memory for zData!" << std::endl; return -1; } // copy data from mwArray to C++ y.GetData(yData, 4); z.GetData(zData, 4); // print output std::cout << "y = " << std::endl; std::cout << yData[0] << ", " << yData[1] << std::endl; std::cout << yData[2] << ", " << yData[3] << std::endl; std::cout << "z = " << std::endl; std::cout << zData[0] << ", " << zData[1] << std::endl; std::cout << zData[2] << ", " << zData[3] << std::endl; // deallocate memory delete [] aData; delete [] zData; delete [] yData; } catch( const mwException& e) { std::cerr << e.what() << std::endl; } // terminate the lib libmyadd2Terminate(); // terminate MCR mclTerminateApplication(); return 0; } 實(shí)驗(yàn)的結(jié)果表明,在C++程序中使用MATLAB編譯產(chǎn)生的C++接口DLL非常容易。 error:mcc編譯m文件出現(xiàn)這樣的錯(cuò)誤提示(例): Error: File "psf3" is a script M-file and cannot be compiled with the current Compiler. matlab complier不能編譯script M-file,請將script M-file轉(zhuǎn)成function m-file 最簡單的一個(gè)轉(zhuǎn)法是:如果你的m文件叫a.m,在開頭加上一句: function a http://hi.baidu.com/minedreamflowers/blog/item/70593b24b5da913bc9955914.html 果然,實(shí)踐才是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)啊,弄了一天,發(fā)現(xiàn)以上文章中都有不同程度的問題,最后按照另一篇文章的做法才把這個(gè)例子弄通了,額,囧啊~~ 【轉(zhuǎn)】VS2008 C++ 調(diào)用MATLAB 2009b 生成的DLL 剛開始學(xué)習(xí)用VC++調(diào)用matlab生成的DLL,找了網(wǎng)上一些資料,難以找到vs2008與MATLAB2009b版本的,按照以往版本做的總是有很多錯(cuò)誤。經(jīng)過兩天努力,終于調(diào)試成功,這里將經(jīng)驗(yàn)總結(jié)一下,以供有需要的人們參考。 實(shí)驗(yàn)環(huán)境: Win7 MATLAB 2009b(安裝路徑:E:\Program Files\MATLAB\R2009a) VS2008 中文版(安裝路徑:E:\Program Files\Microsoft Visual Studio 9.0) 1.Matlab 生成DLL 1.1編譯器的安裝 在matlab中先安裝編譯器,我在第一次安裝的時(shí)候一路y下來,只有一個(gè)compiler,還是最老的。這教育我們要學(xué)會(huì)說N,按照以下步驟操作 >> mbuild -setup Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers [y]/n? n Select a compiler: [1] Lcc-win32 C 2.4.1 [2] Microsoft Visual C++ 6.0 [3] Microsoft Visual C++ .NET 2003 [4] Microsoft Visual C++ 2005 SP1 [5] Microsoft Visual C++ 2008 Express [6] Microsoft Visual C++ 2008 SP1 [0] None Compiler: 6 The default location for Microsoft Visual C++ 2008 SP1 compilers is C:\Program Files\Microsoft Visual Studio 9.0, but that directory does not exist on this machine. Use C:\Program Files\Microsoft Visual Studio 9.0 anyway [y]/n? n Please enter the location of your compiler: [C:\Program Files\Microsoft Visual Studio 9.0] e:\Program Files\Microsoft Visual Studio 9.0 (紅色部分換成你的vs所安裝的地址) Please verify your choices: Compiler: Microsoft Visual C++ 2008 SP1 Location: e:\Program Files\Microsoft Visual Studio 9.0 Are these correct [y]/n? y **************************************************************************** Warning: Applications/components generated using Microsoft Visual Studio 2008 require that the Microsoft Visual Studio 2008 run-time libraries be available on the computer used for deployment. To redistribute your applications/components, be sure that the deployment machine has these run-time libraries. **************************************************************************** Trying to update options file: C:\Users\Administrator\AppData\Roaming\MathWorks\MATLAB\R2009a\compopts.bat From template: E:\PROGRA~1\MATLAB\R2009a\bin\win32\mbuildopts\msvc90compp.bat Done . . . 1.2 DLL的生成 首先新建一個(gè)m文件,文件名為myadd2.m,定義了一個(gè)名為myadd2的函數(shù),代碼如下: ////////////////////////////////////////////////////// function [y,z] = myadd2(a, b) % dummy function, just to demonstrate the idea y = a+b; z = a+2*b; end ///////////////////////////////////// 在MATLAB命令框中輸入以下命令: mcc -W cpplib:libmyadd2 -T link:lib myadd2.m 生成libmyadd2.lib, libmyadd2.h, libmyadd2.dll 等文件,將這三個(gè)文件拷到VS的項(xiàng)目目錄下 2. VS調(diào)用DLL 2.1 新建一個(gè)項(xiàng)目,并設(shè)置環(huán)境 新建一個(gè)win32 控制臺應(yīng)用程序,我取的名字是matlabDll2.當(dāng)然新建其他的項(xiàng)目類型也可以,我這只是個(gè)例子。接下來進(jìn)行配置,在該項(xiàng)目的屬性中進(jìn)行了配置,只對該項(xiàng)目有效。若建新的項(xiàng)目需要重新配置。項(xiàng)目建好后將libmyadd2.lib, libmyadd2.h, libmyadd2.dll拷貝到項(xiàng)目目錄下。 首先配置項(xiàng)目屬性頁/配置屬性/C-C++/常規(guī)/附加包含目錄,請根據(jù)自己電腦上軟件的安裝位置對照設(shè)置,2008與2005不同的地方時(shí)這里要加兩個(gè)目錄,如下圖所示: 其次配置項(xiàng)目屬性頁/配置屬性/鏈接器/常規(guī)/附加庫目錄,請根據(jù)自己電腦上軟件的安裝位置對照設(shè)置,如下圖所示: 然后配置項(xiàng)目屬性頁/配置屬性/鏈接器/輸入/附加依賴性,填入libmyadd2.lib mclmcrrt.lib mclmcr.lib ,如下圖所示: 在這一步俺可吃了大苦頭了,有篇文檔只說添加前兩項(xiàng),俺就照做了,結(jié)果導(dǎo)致運(yùn)行失敗,找了好長時(shí)間也沒發(fā)現(xiàn)錯(cuò)誤,兩天的功夫都在找,結(jié)果就是因?yàn)樯偬盍诉@一項(xiàng),還有其他的一些包含lib,比如libmex.lib libmx.lib ,這里沒填,好像是VC6上要配的。 配置到此結(jié)束 2.2 編寫主程序,調(diào)試運(yùn)行 這段代碼是從別處拷來的,是一段完整代碼,將它粘到matlabDLL2.cpp 主CPP文件中,調(diào)試通過: ////////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include <iostream> #include "mclmcr.h" #include "mclcppclass.h" #include "libmyadd2.h" int _tmain(int argc, _TCHAR* argv[]) { std::cout << "Hello world!" << std::endl; // initialize lib if( !libmyadd2Initialize()) { std::cout << "Could not initialize libmyadd2!" << std::endl; return -1; } try { // declare and initialize a mwArray a(2, 2, mxDOUBLE_CLASS); double *aData; aData = new double[4]; int i; for( i=0; i<4; ++i) { aData[i] = 1.0*i; } // print output std::cout << "a = " << std::endl; std::cout << aData[0] << ",\t" << aData[1] << std::endl; std::cout << aData[2] << ",\t" << aData[3] << std::endl; a.SetData(aData, 4); // declare and initialize b mwArray b(2, 2, mxDOUBLE_CLASS); b(1,1) = 11.; b(1,2) = 12.; b(2,1) = 21.; b(2,2) = 22.; mwArray y(2, 2, mxDOUBLE_CLASS); mwArray z(2, 2, mxDOUBLE_CLASS); // call the function myadd2(2, y, z, a, b); // copy data from mwArray to C++ objects // allocate outputs double *yData, *zData; yData = new double[4]; if( yData == NULL ) { std::cout << "Failed to allocate memory for yData!" << std::endl; return -1; } zData = new double[4]; if( zData == NULL ) { std::cout << "Failed to allocate memory for zData!" << std::endl; return -1; } // copy data from mwArray to C++ y.GetData(yData, 4); z.GetData(zData, 4); // print output std::cout << "y = " << std::endl; std::cout << yData[0] << ",\t" << yData[1] << std::endl; std::cout << yData[2] << ",\t" << yData[3] << std::endl; std::cout << "z = " << std::endl; std::cout << zData[0] << ",\t" << zData[1] << std::endl; std::cout << zData[2] << ",\t" << zData[3] << std::endl; // deallocate memory delete [] aData; delete [] zData; delete [] yData; } catch( const mwException& e) { std::cerr << e.what() << std::endl; } // terminate the lib libmyadd2Terminate(); // terminate MCR mclTerminateApplication(); return 0; } ///////////////////////////////////////////////////////////////////////////// 運(yùn)行結(jié)果如下圖: 問題 我將代碼的標(biāo)紅部分注釋掉了,否則會(huì)出現(xiàn)錯(cuò)誤: 1>c:\users\administrator\documents\visual studio 2008\projects\matlabdll2\matlabdll2\matlabdll2.cpp(14) : error C3861: “mclInitializeApplication_proxy”: 找不到標(biāo)識符 我不知道為什么,大家在調(diào)試的過程如果解決了這個(gè)問題,麻煩告訴一聲:liufengjk_ok@126.com。 致謝 感謝taohe等網(wǎng)友提供的參考! http://blog.csdn.net/infocarrier/archive/2010/09/01/5854522.aspx
|
|