产生的DLL (VS2005, MATLAB7.5, mwArray)
| from:?http://www.simwe.com/forum/thread-801187-1-1.html 程序中使用MATLAB編譯產(chǎn)生的DLL (VS2005, MATLAB7.5, mwArray) 最近有幾個帖子都在討論有關(guān)在C++程序中使用MATLAB編譯產(chǎn)生的動態(tài)鏈接庫DLL。本 來想用原來帖子中給出的m代碼作為例子,無奈那段代碼其實(shí)無法執(zhí)行。為了避免分散注意力,也為了更好地討論問題,于是決定還是另外新開一個主題,以簡單的 例子,和大家一起討論如何在C++程序中使用matlab編譯產(chǎn)生的DLL。 同時MATLAB最新版本R2007b剛剛發(fā)布不久,其中包含編譯器4.7版,有了一些新的特性,于是也借這個例子來驗(yàn)證一下相關(guān)的技術(shù)有沒有發(fā)生大的變化。 最近討論的問題是關(guān)于在C++程序中調(diào)用MATLAB編譯產(chǎn)生的動態(tài)鏈接庫。具體的問題是在 調(diào)用DLL中函數(shù)時傳遞參數(shù)。我們知道,MATLAB可以把m代碼編譯成兩種DLL,分別是C語言接口和C++語言接口的DLL。論壇上的問題是關(guān)于調(diào)用 C++接口的DLL中的函數(shù),所以這里我們就以這種DLL為例來介紹。在C++接口的DLL中,函數(shù)的輸入、輸出參數(shù)都是mwArray對象。所以問題歸 結(jié)為如何在C++程序中使用mwArray。 這個問題本來可以只用一個簡單的C++程序來練習(xí),而不需要MATLAB編譯的DLL。不過為了模擬實(shí)際情況,選擇以一個更為接近實(shí)際的m代碼作為例子。在這個例子中,輸入輸出都是矩陣,至于標(biāo)量,它也是一個一行、一列的矩陣。 實(shí)驗(yàn)環(huán)境:Windows 2003 Std Server with SP2 (En),MATLAB R2007b,Visual Studio 2005。MATLAB安裝路徑:h:MATLABR2007b。 實(shí)驗(yàn)內(nèi)容:把一個簡單的m代碼編譯成C++接口的DLL,然后在C++程序中調(diào)用。為了簡單起見,這里的C++程序是一個Win32 Console程序,而不是Windows圖形界面的程序,不過不妨礙我們的討論。 下面是這個例子用到的m代碼。它定義了一個名為myadd2的函數(shù): [Copy to clipboard]?[ - ] CODE: function [y,z] = myadd2(a, b) % dummy function, just to demonstrate the idea y = a+b; z = a+2*b; end 首先把這個函數(shù)編譯成C++接口的DLL。為此,我們需要先設(shè)置MATLAB編譯器。具體做法是在MATLAB命令行執(zhí)行“mbuild -setup”。然后用下面這行命令把myadd2函數(shù)編譯成一個C++接口的DLL: [Copy to clipboard]?[ - ] CODE: mcc -W cpplib:libmyadd2 -T link:lib myadd2 結(jié)果,我們將會得到包含libmyadd2.dll,libmyadd2.ctf,libmyadd2.h,libmyadd2.lib等在內(nèi)的一些文件。接下來我們只需要這四個文件。請注意:在MATLAB R2007b之前,這些文件都會在和編譯 的m代碼所在的目錄中,而在MATLAB R2007b,缺省情況下這些文件會在Documents and Settings中用戶的My Documents目錄中。 此時,打開libmyadd2.h看看,在文件的最下面我們可以發(fā)現(xiàn)C++接口的函數(shù)定義。仔細(xì)觀察過后,我們可以發(fā)現(xiàn),這個接口函數(shù)的參數(shù)是按照這樣的順序定義的:輸出參數(shù)的個數(shù)、輸出參數(shù)、以及輸入?yún)?shù)。 然后在VS2005中創(chuàng)建一個Win32 Console的VC++工程,我在測試時取名為testmyadd2_r2007b。把以上四個文件拷貝到VC++工程的源代碼所在目錄。 接下來設(shè)置VC++,讓它能找到MATLAB接口函數(shù)的定義及連接庫函數(shù)。可以有兩種設(shè)置方式:一種是改VS2005中關(guān)于VC++的設(shè)置,這樣的好處是每個新的工程都能自動獲得這個設(shè)定;而另一種是只改當(dāng)前工程的設(shè)置,也就是設(shè)置只對該工程有效。這里用后一種方式。 在VS2005中打開工程testmyadd2_r2007b,選擇菜單“Project-->Properties,在出來的對話框上,把MATLAB提供的include路徑加到VC++的頭文件搜索路徑。如圖所示: ? ?vs2005_matlabr2007b_inc01.gif?(25.26 KB) ? 然后把相應(yīng)的lib所在目錄加到linker的額外搜索路徑上。如圖所示: ?vs2005_matlabr2007b_lib01.gif?(25.99 KB)?接下來,告訴VC++,我們的這個程序需要連接到另外兩個額外的庫函數(shù):libmyadd2.lib和mclmcrrt.lib。中間用空格隔開。如圖所示: ?vs2005_matlabr2007b_lib02.gif?(23.16 KB)? 最后則是程序代碼。這個程序只有一個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; ?? ??? /* Initialize the MCR */? ?? ??? 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; } 2007-10-6 23:18 ?vs2005_matlabr2007b_result.gif?(9.26 KB)? 實(shí)驗(yàn)的結(jié)果表明,在C++程序中使用MATLAB編譯產(chǎn)生的C++接口DLL非常容易。 mwArray也很容易使用。另外,最新的MATLAB R2007b中關(guān)于這部分并沒有什么大的變化。這個練習(xí)適合MATLAB 7.0以后直到MATLAB R2007b的所有版本。 ask: 就我個人6.5混編的經(jīng)驗(yàn),我很少弄DLL,直接編譯M文件為cpp,h文件即可,VC工程中引用,按.h文件格式調(diào)用即可。 這樣混編基本沒有任何難度,將MATLAB程序看成MFC一個類即可,看看extern里面 相關(guān)頭文件的定義,跟看MSDN一樣。 拋開mclTerminateApplication();這些,這應(yīng)該是一個通用的辦法 手頭只有6.5,不知道7.5還能生成cpp么? answer: 從matlab7.0開始,其編譯器的功能就和以前版本不一樣了。它不再把m代碼翻譯成C/C++源代碼,而是對m代碼作個簡單的 wrapper,通常以動態(tài)鏈接庫的形式提供給用戶以方便用戶在其他的程序中使用。所以,在matlab 7.x,編譯m代碼不能得到以前那種意義的C/C++源程序。不過,僅從軟件開發(fā)的角度來看,我覺得用DLL來打包更為方便。如果m函數(shù)的接口不變,那么每次改變m代碼后,我們只需重新編譯m代碼,獲得新的DLL及CTF,而不需要重新編譯VC客戶程序。這在開發(fā)大型軟件時有很大的優(yōu)越性。 多謝taohe的文章,我想問一下,ctf文件是干嘛用的,謝謝,記得matlab 6.5版里面編譯為DLL時沒這個東西啊。 這是matlab7.0以后matlab編譯器的新特性。它和舊版技術(shù)不兼容。ctf其實(shí)就是一個zip文件,其中包含加密或者說編碼過的一些m代碼。其中有你自己的代碼,以及matlab編譯器通過分析你的代碼根據(jù)依賴關(guān)系找到的其他一些m代碼。 |
轉(zhuǎn)載于:https://www.cnblogs.com/mfryf/archive/2012/02/16/2354285.html
總結(jié)
以上是生活随笔為你收集整理的产生的DLL (VS2005, MATLAB7.5, mwArray)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Direct3D学习_绘制
- 下一篇: 简单代码生成器原理剖析(一)