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