999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于C++/CLI實現托管代碼與非托管代碼的交互

2013-10-20 08:36:00馮士德
微型電腦應用 2013年1期
關鍵詞:效率語言

馮士德

0 引言

由于托管代碼與非托管代碼在運行機制上存在差異,導致了這兩者間無法實現直接的交互。雖然微軟在.Net Framework中提供了P/Invoke技術來解決托管代碼與非托管代碼之間的互操作問題[1]。但是使用 P/Invoke的 DllImport方法,僅能實現在托管代碼中調用非托管代碼中的函數,而無法實現對非托管代碼中類的引用。為了解決這個問題,通常做法是建立函數接口對非托管代碼中的類進行包裝,然后在托管代碼中使用 P/Invoke方法,通過調用函數接口間接調用非托管代碼中所定義的類。但是在托管代碼與非托管代碼互操作頻繁的項目中,通過函數接口調用非托管代碼中的類,將會破壞面向對象的編程思想,同時影響代碼的執行效率。為了解決這一問題,本文就使用 C++/CLI語言實現在托管代碼與非托管代碼之間的交互進行了研究,并以 C#語言為例解釋說明了其具體的實現的方法。

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

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

圖1 C++/CLI代碼編譯機制

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

圖2 C++/CLI、托管代碼、非托管代碼關系

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

2 交互方法

由于托管代碼與非托管代碼的實現機制不同,所以在這兩者間無法實現直接的函數調用或數據傳遞操作。而C++/CLI代碼恰恰介于托管與非托管之間,所以以C++/CLI代碼為中介,實現托管與非托管代碼之間的交互,是一個可行的方法,也是本文所研究的重點。

2.1 基本思想

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

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

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

a) 在托管代碼與非托管代碼之間傳遞數據

b) 在托管代碼與非托管代碼之間轉換內存地址

C++/CLI代碼通過對非托管代碼中的類,進行包裝來完成以上兩項工作。

首先,使用C++/CLI代碼聲明一個非托管類的包裝類。此包裝類中必須含有一個指向非托管類實例的指針,這樣,包裝類便能夠通過這個指針,將托管代碼對非托管類實例的操作請求,傳遞給非托管類實例。

然后,為包裝類添加構造函數與析構函數。在構造函數中實現生成非托管類實例的操作,并將其地址賦給包裝類中非托管類實例的指針。在析構函數中則應實現刪除非托管類實例的操作。

最后,為包裝類添加與非托管類中的公共成員屬性及公共成員函數對應的成員屬性與成員函數。當托管代碼需要讀寫非托管類中的公共成員屬性時,托管代碼通過讀寫包裝類中相應的成員屬性間接實現讀寫操作。托管代碼對非托管類中成員函數的調用操作亦是如此。

可見使用C++/CLI代碼進行集成是一種代碼級別的集成方式,通過 C++/CLI代碼可以非常方便地對非托管代碼中的類進行包裝。所生成的包裝類完全符合CLI代碼規范,并可以在托管代碼中自由地調用,因此能夠實現托管代碼與非托管代碼之間的無縫集成。

2.2 交互方法舉例

本節以C#語言為例,說明使用C++/CLI語言對非托管代碼中的導出類進行包裝的具體方法。并以非托管代碼中的導出類UnmanagedClass為樣例對其進行包裝,其頭文件聲明如下:

UnmanagedClsss類中包括一個 int型的公共屬性iParamA、一個公共函數Add以及相應的構造函數和析構函數。Add函數實現了將兩個輸入參數相加并返回結果的簡單功能。這些函數與屬性均為公共類型(pubulic)。由于非托管類中私有類型(private)的成員屬性與成員函數僅在類的內部可見無需導出,所以在該例中省略了私有成員屬性與私有成員函數。

為了將UnmanagedClass包裝為托管代碼中的類,使用C++/CLI代碼聲明 ManagedClass類對其進行包裝。ManagedClass的頭文件聲明如下:

ManagedClass作為 UnmanagedClass被封裝后的托管類,根據托管代碼的規則,在聲明ManagedClass時必須同時指定其namespace。在本例中將其設為“SampleSolution”。

在 ManagedClass中聲明一個 protected的成員屬性pInstance,并設置該成員屬性為UnmanagedClass類的指針。當ManagedClass的構造函數被調用時,在構造函數中生成被包裝類UnmanagedClass的實例,并將其地址保存于這個指針屬性中。之后所有對ManagedClass的操作都將通過此指針傳遞給UnmanagedClass。ManagedClass的構造與析構函數如下:

為了將UnmanagedClass中的每個公共成員屬性導出,在ManagedClass中為UnmanagedClass的每個公共成員屬性建立一個對應的屬性。對ManagedClass中的公共屬性執行讀寫操作時,將實際的操作通過ManagedClass::pInstance指針傳遞給 UnmanagedClass實例,代碼舉例如下:

從示例代碼中可知,當對ManagedClass的iParamA執行讀操作時,實際返回的是由ManagedClass::pInstance所指UnmanagedClass實例中成員屬性iParamA的值。對iParamA的寫操作也類似,實際寫入的是UnmanagedClass實例中成員屬性iParamA。

為了將ManagedClass中的每個公共成員函數導出,也采取與導出公共成員屬性相似的方法。在ManagedClass中為UnmanagedClass的每個公共成員函數聲明一個對應的公共成員函數,代碼舉例如下:

當ManagedClass中的成員函數被調用時,此調用操作將通過 ManagedClass::pInstance指針找到 UnmanagedClass中所對應的成員函數,并將調用參數傳遞給它,然后執行該函數并將返回值返回給ManagedClass的成員函數,最后由ManagedClass的成員函數將返回值返回給函數調用者。

3 執行效率測試及其結果分析

為了進一步研究使用C++/CLI語言技術實現托管代碼與非托管代碼之間交互的方式是否會降低非托管代碼執行效率的問題,本文以冒泡排序法為案例對該交互方式的代碼執行效率進行了測試。

3.1 測試方法

首先以 C++語言編制一個基于非托管代碼的 DLL文件,該DLL文件中包應含一個實現冒泡排序法的導出類。然后使用C++/CLI語言對算法DLL文件進行包裝,生成一個介于托管與非托管之間的DLL文件。最后使用C#語言編寫一個調用程序來調用這個DLL文件,以此實現冒泡排序的功能。

同時作為對比試驗的參照物,使用 C++語言編寫另一個調用程序。該程序直接調用非托管的算法DLL文件實現冒泡排序功能。

通過對比這兩個分別由C#語言與C++語言實現的調用程序的執行時間,便可以判斷經過包裝后的非托管代碼的執行效率是否會降低。所生成的實驗用DLL文件與調用程序的結構,如圖4所示:

圖4 試驗用程序結構

3.2 試驗結果

為了得到相對準確的試驗結果,使用 C#調用程序與C++調用程序分別執行對2萬、4萬、6萬、8萬、10萬個隨機數的排序操作,并分別記錄其執行時間。

同時考慮到Windows是多線程操作系統,為了減少線程間調度對本次試驗結果產生的影響,在執行測試程序前已關閉了所有其它應用程序。并且對各個數量級別的測試分別執行 10次并取其平均數作為最后的試驗結果。在CPU 為2.4GHz、內存2G、Win7操作系統的普通臺式機環境中,實際測試結果,如圖5所示:

圖5 試驗結果對比

由圖5中顯示的試驗數據可知,經過包裝的非托管代碼在托管代碼中的執行效率與直接在非托管代碼中的執行效率的差距在上下千分之三之內,在部分情況下甚至要稍高于直接在非托管代碼中的執行效率。通過對比這兩組試驗數據,可以近似認為非托管代碼在經過包裝后的執行效率等同于包裝前的執行效率,代碼執行效率幾乎不受包裝影響。

4 結束語

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

當前能夠實現在托管代碼與非托管代碼之間交互的技術有很多,例如利用隨機數據文件作為交互中介[3]等。但是每種交互方式都相對的存在其優缺點,在軟件項目中必須根據具體需求來決定選取何種交互方法。所以針對各種實現托管代碼與非托管代碼交互技術之間優缺點的研究還值得繼續深入。

[1]彭邦倫.C#托管代碼調用非托管代碼參數傳遞的實現方式.[J]軟件導刊2011,10(1)

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

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

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

[5]錢能.C++程序設計教程.[M]清華大學出版社, 1999年4月 ISBN:7-302-03421-4

[6]蔡昭權.C#和C++數據傳遞的研究與實現.[J]計算機應用與軟件2009,26(3)

猜你喜歡
效率語言
提升朗讀教學效率的幾點思考
甘肅教育(2020年14期)2020-09-11 07:57:42
注意實驗拓展,提高復習效率
語言是刀
文苑(2020年4期)2020-05-30 12:35:30
讓語言描寫搖曳多姿
效率的價值
商周刊(2017年9期)2017-08-22 02:57:49
多向度交往對語言磨蝕的補正之道
累積動態分析下的同聲傳譯語言壓縮
我有我語言
跟蹤導練(一)2
“錢”、“事”脫節效率低
中國衛生(2014年11期)2014-11-12 13:11:32
主站蜘蛛池模板: 精品无码国产一区二区三区AV| 久久www视频| 91久久青青草原精品国产| 国产成人三级在线观看视频| 亚洲国产中文在线二区三区免| 国产精品任我爽爆在线播放6080| 91美女视频在线| 国产免费福利网站| 国产最爽的乱婬视频国语对白| 第九色区aⅴ天堂久久香| 乱人伦中文视频在线观看免费| 福利一区在线| 亚洲综合日韩精品| 精品成人一区二区三区电影| 精品国产乱码久久久久久一区二区| 午夜天堂视频| 久久天天躁夜夜躁狠狠| 国产www网站| 亚洲欧美日韩久久精品| 华人在线亚洲欧美精品| 亚洲无码高清一区二区| 最新日韩AV网址在线观看| 久久精品国产精品青草app| 永久免费av网站可以直接看的| 国产69囗曝护士吞精在线视频| 欧美乱妇高清无乱码免费| 国产激情无码一区二区APP| 91探花在线观看国产最新| 午夜福利免费视频| 无码国产偷倩在线播放老年人| 亚洲一区二区精品无码久久久| 91成人在线免费观看| 乱系列中文字幕在线视频| 欧美午夜小视频| 午夜毛片免费观看视频 | 大香网伊人久久综合网2020| 一级福利视频| 伊人成人在线| 欧美一级特黄aaaaaa在线看片| 欧美va亚洲va香蕉在线| 国产高清在线丝袜精品一区| 久久国产精品波多野结衣| 国内精品手机在线观看视频| 亚洲av色吊丝无码| 亚洲欧美精品在线| 亚洲无限乱码| 丁香五月亚洲综合在线 | 国产男人天堂| 呦女亚洲一区精品| 精品国产成人高清在线| 伊人久久青草青青综合| 99视频免费观看| 日韩AV无码一区| 在线免费不卡视频| 国产女人在线视频| 亚洲综合精品香蕉久久网| 免费女人18毛片a级毛片视频| 欧美狠狠干| 日韩成人在线视频| 久青草网站| 国产欧美在线视频免费| 69视频国产| 国产高清无码麻豆精品| 欧美日韩成人在线观看| 亚洲色婷婷一区二区| 日韩久草视频| 少妇露出福利视频| 欧美亚洲香蕉| 欧美黑人欧美精品刺激| 国产免费久久精品99re丫丫一| 精品国产免费观看一区| 欧美特黄一级大黄录像| 黄色网在线| AV无码一区二区三区四区| 国产黑人在线| 色悠久久久| 日本福利视频网站| 日韩精品少妇无码受不了| 日本午夜精品一本在线观看| 亚洲第一成年网| 国产电话自拍伊人| 成人中文字幕在线|