亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于C++/CLI實(shí)現(xiàn)托管代碼與非托管代碼的交互

        2013-10-20 08:36:00馮士德
        微型電腦應(yīng)用 2013年1期
        關(guān)鍵詞:效率語(yǔ)言

        馮士德

        0 引言

        由于托管代碼與非托管代碼在運(yùn)行機(jī)制上存在差異,導(dǎo)致了這兩者間無(wú)法實(shí)現(xiàn)直接的交互。雖然微軟在.Net Framework中提供了P/Invoke技術(shù)來(lái)解決托管代碼與非托管代碼之間的互操作問(wèn)題[1]。但是使用 P/Invoke的 DllImport方法,僅能實(shí)現(xiàn)在托管代碼中調(diào)用非托管代碼中的函數(shù),而無(wú)法實(shí)現(xiàn)對(duì)非托管代碼中類(lèi)的引用。為了解決這個(gè)問(wèn)題,通常做法是建立函數(shù)接口對(duì)非托管代碼中的類(lèi)進(jìn)行包裝,然后在托管代碼中使用 P/Invoke方法,通過(guò)調(diào)用函數(shù)接口間接調(diào)用非托管代碼中所定義的類(lèi)。但是在托管代碼與非托管代碼互操作頻繁的項(xiàng)目中,通過(guò)函數(shù)接口調(diào)用非托管代碼中的類(lèi),將會(huì)破壞面向?qū)ο蟮木幊趟枷?,同時(shí)影響代碼的執(zhí)行效率。為了解決這一問(wèn)題,本文就使用 C++/CLI語(yǔ)言實(shí)現(xiàn)在托管代碼與非托管代碼之間的交互進(jìn)行了研究,并以 C#語(yǔ)言為例解釋說(shuō)明了其具體的實(shí)現(xiàn)的方法。

        1 C++/CLI與托管/非托管代碼

        C++/CLI是標(biāo)準(zhǔn) C++語(yǔ)言與CLI(Common Language Infrastructure)的集成。在代碼編制方法上,它在保留了標(biāo)準(zhǔn) C++語(yǔ)言的語(yǔ)法并對(duì)其進(jìn)行了擴(kuò)展以符合 CLI語(yǔ)言的要求。所以可以將C++/CLI語(yǔ)言簡(jiǎn)單的看作為標(biāo)準(zhǔn)C++語(yǔ)言的一個(gè)擴(kuò)展。但在代碼編譯與執(zhí)行的原理上,它卻與標(biāo)準(zhǔn)C++語(yǔ)言截然不同,它遵守了CLI語(yǔ)言的規(guī)范。與其他CLI語(yǔ)言相同,C++/CLI語(yǔ)言在被編譯時(shí)將會(huì)被編譯成托管的微軟中間語(yǔ)言(MSIL)代碼,之后再由實(shí)時(shí)(JIT)編譯器在執(zhí)行時(shí)將中間語(yǔ)言代碼編譯為本機(jī)代碼后執(zhí)行[2]。不過(guò)又區(qū)別于其他CLI語(yǔ)言,C++/CLI代碼中以#pragma unmanaged標(biāo)記顯式標(biāo)注的代碼段將被直接編譯為本地二進(jìn)制代碼。所以C++/CLI代碼在經(jīng)過(guò)編譯,最后所生成的是托管代碼與非托管代碼的混合程序集,如圖1所示:

        圖1 C++/CLI代碼編譯機(jī)制

        可見(jiàn)C++/CLI代碼身處托管代碼與非托管代碼之間,其3者關(guān)系,如圖2所示:

        圖2 C++/CLI、托管代碼、非托管代碼關(guān)系

        C++/CLI代碼,就好似在托管世界與非托管世界之間架起了一座橋梁,打通了兩者之間的壁壘。通過(guò)在源代碼層次的交互,C++/CLI提供了一個(gè)非常有價(jià)值的跨編程語(yǔ)言的集成方式。借助于這種方式,可以將非托管代碼中的本地類(lèi)在托管的世界中發(fā)布,這使得在同一個(gè)軟件項(xiàng)目中,充分調(diào)動(dòng)托管代碼世界與非托管代碼世界中,豐富軟件資源成為了可能。

        2 交互方法

        由于托管代碼與非托管代碼的實(shí)現(xiàn)機(jī)制不同,所以在這兩者間無(wú)法實(shí)現(xiàn)直接的函數(shù)調(diào)用或數(shù)據(jù)傳遞操作。而C++/CLI代碼恰恰介于托管與非托管之間,所以以C++/CLI代碼為中介,實(shí)現(xiàn)托管與非托管代碼之間的交互,是一個(gè)可行的方法,也是本文所研究的重點(diǎn)。

        2.1 基本思想

        以C++/CLI代碼為中介,實(shí)現(xiàn)托管代碼與非托管代碼交互的方式,如圖3所示:

        圖3 托管代碼與非托管代碼交互方式

        作為托管代碼與非托管代碼之間的中介,C++/CLI代碼必須完成以下兩項(xiàng)主要工作:

        a) 在托管代碼與非托管代碼之間傳遞數(shù)據(jù)

        b) 在托管代碼與非托管代碼之間轉(zhuǎn)換內(nèi)存地址

        C++/CLI代碼通過(guò)對(duì)非托管代碼中的類(lèi),進(jìn)行包裝來(lái)完成以上兩項(xiàng)工作。

        首先,使用C++/CLI代碼聲明一個(gè)非托管類(lèi)的包裝類(lèi)。此包裝類(lèi)中必須含有一個(gè)指向非托管類(lèi)實(shí)例的指針,這樣,包裝類(lèi)便能夠通過(guò)這個(gè)指針,將托管代碼對(duì)非托管類(lèi)實(shí)例的操作請(qǐng)求,傳遞給非托管類(lèi)實(shí)例。

        然后,為包裝類(lèi)添加構(gòu)造函數(shù)與析構(gòu)函數(shù)。在構(gòu)造函數(shù)中實(shí)現(xiàn)生成非托管類(lèi)實(shí)例的操作,并將其地址賦給包裝類(lèi)中非托管類(lèi)實(shí)例的指針。在析構(gòu)函數(shù)中則應(yīng)實(shí)現(xiàn)刪除非托管類(lèi)實(shí)例的操作。

        最后,為包裝類(lèi)添加與非托管類(lèi)中的公共成員屬性及公共成員函數(shù)對(duì)應(yīng)的成員屬性與成員函數(shù)。當(dāng)托管代碼需要讀寫(xiě)非托管類(lèi)中的公共成員屬性時(shí),托管代碼通過(guò)讀寫(xiě)包裝類(lèi)中相應(yīng)的成員屬性間接實(shí)現(xiàn)讀寫(xiě)操作。托管代碼對(duì)非托管類(lèi)中成員函數(shù)的調(diào)用操作亦是如此。

        可見(jiàn)使用C++/CLI代碼進(jìn)行集成是一種代碼級(jí)別的集成方式,通過(guò) C++/CLI代碼可以非常方便地對(duì)非托管代碼中的類(lèi)進(jìn)行包裝。所生成的包裝類(lèi)完全符合CLI代碼規(guī)范,并可以在托管代碼中自由地調(diào)用,因此能夠?qū)崿F(xiàn)托管代碼與非托管代碼之間的無(wú)縫集成。

        2.2 交互方法舉例

        本節(jié)以C#語(yǔ)言為例,說(shuō)明使用C++/CLI語(yǔ)言對(duì)非托管代碼中的導(dǎo)出類(lèi)進(jìn)行包裝的具體方法。并以非托管代碼中的導(dǎo)出類(lèi)UnmanagedClass為樣例對(duì)其進(jìn)行包裝,其頭文件聲明如下:

        UnmanagedClsss類(lèi)中包括一個(gè) int型的公共屬性iParamA、一個(gè)公共函數(shù)Add以及相應(yīng)的構(gòu)造函數(shù)和析構(gòu)函數(shù)。Add函數(shù)實(shí)現(xiàn)了將兩個(gè)輸入?yún)?shù)相加并返回結(jié)果的簡(jiǎn)單功能。這些函數(shù)與屬性均為公共類(lèi)型(pubulic)。由于非托管類(lèi)中私有類(lèi)型(private)的成員屬性與成員函數(shù)僅在類(lèi)的內(nèi)部可見(jiàn)無(wú)需導(dǎo)出,所以在該例中省略了私有成員屬性與私有成員函數(shù)。

        為了將UnmanagedClass包裝為托管代碼中的類(lèi),使用C++/CLI代碼聲明 ManagedClass類(lèi)對(duì)其進(jìn)行包裝。ManagedClass的頭文件聲明如下:

        ManagedClass作為 UnmanagedClass被封裝后的托管類(lèi),根據(jù)托管代碼的規(guī)則,在聲明ManagedClass時(shí)必須同時(shí)指定其namespace。在本例中將其設(shè)為“SampleSolution”。

        在 ManagedClass中聲明一個(gè) protected的成員屬性pInstance,并設(shè)置該成員屬性為UnmanagedClass類(lèi)的指針。當(dāng)ManagedClass的構(gòu)造函數(shù)被調(diào)用時(shí),在構(gòu)造函數(shù)中生成被包裝類(lèi)UnmanagedClass的實(shí)例,并將其地址保存于這個(gè)指針屬性中。之后所有對(duì)ManagedClass的操作都將通過(guò)此指針傳遞給UnmanagedClass。ManagedClass的構(gòu)造與析構(gòu)函數(shù)如下:

        為了將UnmanagedClass中的每個(gè)公共成員屬性導(dǎo)出,在ManagedClass中為UnmanagedClass的每個(gè)公共成員屬性建立一個(gè)對(duì)應(yīng)的屬性。對(duì)ManagedClass中的公共屬性執(zhí)行讀寫(xiě)操作時(shí),將實(shí)際的操作通過(guò)ManagedClass::pInstance指針傳遞給 UnmanagedClass實(shí)例,代碼舉例如下:

        從示例代碼中可知,當(dāng)對(duì)ManagedClass的iParamA執(zhí)行讀操作時(shí),實(shí)際返回的是由ManagedClass::pInstance所指UnmanagedClass實(shí)例中成員屬性iParamA的值。對(duì)iParamA的寫(xiě)操作也類(lèi)似,實(shí)際寫(xiě)入的是UnmanagedClass實(shí)例中成員屬性iParamA。

        為了將ManagedClass中的每個(gè)公共成員函數(shù)導(dǎo)出,也采取與導(dǎo)出公共成員屬性相似的方法。在ManagedClass中為UnmanagedClass的每個(gè)公共成員函數(shù)聲明一個(gè)對(duì)應(yīng)的公共成員函數(shù),代碼舉例如下:

        當(dāng)ManagedClass中的成員函數(shù)被調(diào)用時(shí),此調(diào)用操作將通過(guò) ManagedClass::pInstance指針找到 UnmanagedClass中所對(duì)應(yīng)的成員函數(shù),并將調(diào)用參數(shù)傳遞給它,然后執(zhí)行該函數(shù)并將返回值返回給ManagedClass的成員函數(shù),最后由ManagedClass的成員函數(shù)將返回值返回給函數(shù)調(diào)用者。

        3 執(zhí)行效率測(cè)試及其結(jié)果分析

        為了進(jìn)一步研究使用C++/CLI語(yǔ)言技術(shù)實(shí)現(xiàn)托管代碼與非托管代碼之間交互的方式是否會(huì)降低非托管代碼執(zhí)行效率的問(wèn)題,本文以冒泡排序法為案例對(duì)該交互方式的代碼執(zhí)行效率進(jìn)行了測(cè)試。

        3.1 測(cè)試方法

        首先以 C++語(yǔ)言編制一個(gè)基于非托管代碼的 DLL文件,該DLL文件中包應(yīng)含一個(gè)實(shí)現(xiàn)冒泡排序法的導(dǎo)出類(lèi)。然后使用C++/CLI語(yǔ)言對(duì)算法DLL文件進(jìn)行包裝,生成一個(gè)介于托管與非托管之間的DLL文件。最后使用C#語(yǔ)言編寫(xiě)一個(gè)調(diào)用程序來(lái)調(diào)用這個(gè)DLL文件,以此實(shí)現(xiàn)冒泡排序的功能。

        同時(shí)作為對(duì)比試驗(yàn)的參照物,使用 C++語(yǔ)言編寫(xiě)另一個(gè)調(diào)用程序。該程序直接調(diào)用非托管的算法DLL文件實(shí)現(xiàn)冒泡排序功能。

        通過(guò)對(duì)比這兩個(gè)分別由C#語(yǔ)言與C++語(yǔ)言實(shí)現(xiàn)的調(diào)用程序的執(zhí)行時(shí)間,便可以判斷經(jīng)過(guò)包裝后的非托管代碼的執(zhí)行效率是否會(huì)降低。所生成的實(shí)驗(yàn)用DLL文件與調(diào)用程序的結(jié)構(gòu),如圖4所示:

        圖4 試驗(yàn)用程序結(jié)構(gòu)

        3.2 試驗(yàn)結(jié)果

        為了得到相對(duì)準(zhǔn)確的試驗(yàn)結(jié)果,使用 C#調(diào)用程序與C++調(diào)用程序分別執(zhí)行對(duì)2萬(wàn)、4萬(wàn)、6萬(wàn)、8萬(wàn)、10萬(wàn)個(gè)隨機(jī)數(shù)的排序操作,并分別記錄其執(zhí)行時(shí)間。

        同時(shí)考慮到Windows是多線(xiàn)程操作系統(tǒng),為了減少線(xiàn)程間調(diào)度對(duì)本次試驗(yàn)結(jié)果產(chǎn)生的影響,在執(zhí)行測(cè)試程序前已關(guān)閉了所有其它應(yīng)用程序。并且對(duì)各個(gè)數(shù)量級(jí)別的測(cè)試分別執(zhí)行 10次并取其平均數(shù)作為最后的試驗(yàn)結(jié)果。在CPU 為2.4GHz、內(nèi)存2G、Win7操作系統(tǒng)的普通臺(tái)式機(jī)環(huán)境中,實(shí)際測(cè)試結(jié)果,如圖5所示:

        圖5 試驗(yàn)結(jié)果對(duì)比

        由圖5中顯示的試驗(yàn)數(shù)據(jù)可知,經(jīng)過(guò)包裝的非托管代碼在托管代碼中的執(zhí)行效率與直接在非托管代碼中的執(zhí)行效率的差距在上下千分之三之內(nèi),在部分情況下甚至要稍高于直接在非托管代碼中的執(zhí)行效率。通過(guò)對(duì)比這兩組試驗(yàn)數(shù)據(jù),可以近似認(rèn)為非托管代碼在經(jīng)過(guò)包裝后的執(zhí)行效率等同于包裝前的執(zhí)行效率,代碼執(zhí)行效率幾乎不受包裝影響。

        4 結(jié)束語(yǔ)

        當(dāng)前微軟.Net平臺(tái)的發(fā)展勢(shì)頭正勁,托管代碼的執(zhí)行效率也正逐步逼近非托管代碼,很多軟件開(kāi)發(fā)公司也都將.Net作為其主要產(chǎn)品開(kāi)發(fā)平臺(tái)。.Net平臺(tái)的發(fā)展正按照微軟的規(guī)劃突飛猛進(jìn),好似無(wú)所不能。但是C++語(yǔ)言經(jīng)過(guò)了這么多年的發(fā)展與積累,數(shù)以萬(wàn)計(jì)的程序員以C++語(yǔ)言開(kāi)發(fā)了海量的應(yīng)用。特別是以科學(xué)計(jì)算、底層硬件通信為代表的,對(duì)代碼執(zhí)行效率、系統(tǒng)響應(yīng)速度有較高要求的應(yīng)用,多以C++語(yǔ)言實(shí)現(xiàn)。如果僅以.Net為開(kāi)發(fā)平臺(tái),將不得不放棄在以 C++語(yǔ)言為代表的非托管代碼世界中現(xiàn)存的眾多寶貴軟件資源。而隨著 C++/CLI語(yǔ)言的出現(xiàn),它以一種極其簡(jiǎn)單且高效的方式,打通了托管世界與非托管世界之間的壁壘,為我們?cè)?Net平臺(tái)的開(kāi)發(fā)中充分的利用現(xiàn)有非托管軟件資源提供了有效的途徑。

        當(dāng)前能夠?qū)崿F(xiàn)在托管代碼與非托管代碼之間交互的技術(shù)有很多,例如利用隨機(jī)數(shù)據(jù)文件作為交互中介[3]等。但是每種交互方式都相對(duì)的存在其優(yōu)缺點(diǎn),在軟件項(xiàng)目中必須根據(jù)具體需求來(lái)決定選取何種交互方法。所以針對(duì)各種實(shí)現(xiàn)托管代碼與非托管代碼交互技術(shù)之間優(yōu)缺點(diǎn)的研究還值得繼續(xù)深入。

        [1]彭邦倫.C#托管代碼調(diào)用非托管代碼參數(shù)傳遞的實(shí)現(xiàn)方式.[J]軟件導(dǎo)刊2011,10(1)

        [2]鄭阿奇.Visual C++ .NET 2010 開(kāi)發(fā)實(shí)踐-基于C++/CLI.[M]北京,電子工業(yè)出版社 2010年 12月 ISBN:978-7-121-12153-1

        [3]何淼,崔松健.一種基于隨機(jī)文件的C#與非托管C代碼交互模式.[J]信息化研究2011,37(2)

        [4]Jeffrey Richter.CLR via C#(第3版).[M]清華大學(xué)出版社 2010年9月 ISBN:978-7-302-23259-9

        [5]錢(qián)能.C++程序設(shè)計(jì)教程.[M]清華大學(xué)出版社, 1999年4月 ISBN:7-302-03421-4

        [6]蔡昭權(quán).C#和C++數(shù)據(jù)傳遞的研究與實(shí)現(xiàn).[J]計(jì)算機(jī)應(yīng)用與軟件2009,26(3)

        猜你喜歡
        效率語(yǔ)言
        提升朗讀教學(xué)效率的幾點(diǎn)思考
        甘肅教育(2020年14期)2020-09-11 07:57:42
        注意實(shí)驗(yàn)拓展,提高復(fù)習(xí)效率
        語(yǔ)言是刀
        文苑(2020年4期)2020-05-30 12:35:30
        讓語(yǔ)言描寫(xiě)搖曳多姿
        效率的價(jià)值
        商周刊(2017年9期)2017-08-22 02:57:49
        多向度交往對(duì)語(yǔ)言磨蝕的補(bǔ)正之道
        累積動(dòng)態(tài)分析下的同聲傳譯語(yǔ)言壓縮
        我有我語(yǔ)言
        跟蹤導(dǎo)練(一)2
        “錢(qián)”、“事”脫節(jié)效率低
        精品日产一区2区三区| 国产盗摄xxxx视频xxxx| 欲色天天网综合久久| 国产卡一卡二卡3卡4乱码| 国产精品久久久久影院嫩草| 97人妻视频妓女网| 国产精品av网站在线| 成人国产一区二区三区| 免费午夜爽爽爽www视频十八禁| 边添小泬边狠狠躁视频| 男人靠女人免费视频网站| 亚洲毛片在线播放| 亚洲视频一区二区三区免费| 亚洲国产中文字幕在线视频综合| www夜插内射视频网站| 国产精品a免费一区久久电影| 亚洲精品久久久久中文字幕二区| 亚洲a人片在线观看网址| 亚洲中文高清乱码av中文| 狠狠色欧美亚洲狠狠色www| 欧美操逼视频| 国产主播无套内射一区| 偷偷夜夜精品一区二区三区蜜桃| 亚洲2022国产成人精品无码区| 国产亚洲人成a在线v网站| 在线观看国产精品91| 国产精品毛片一区二区三区| 日韩av高清在线观看| 久久综合给合久久狠狠狠97色69| 成人xx免费无码| 国产成人高清亚洲一区二区| 国产在线一区二区三区香蕉| 无码人妻一区二区三区在线 | 久久免费亚洲免费视频| 国产亚洲精品精品精品| 北条麻妃在线视频观看| 成年男人裸j照无遮挡无码| 美女被内射很爽的视频网站| 亚洲精品白浆高清久久久久久| 人妻av无码系列一区二区三区| 国内揄拍国内精品|