C++,DLL,COM,COM+概述

在windows下使用c++編寫代碼的人代碼複用的常用方式大概就是c++、dll和com
一、c++代碼重用的缺陷
    以前的c++開發人員複用代碼的方式大概就是獲得一套.h和.cpp文件,然後把這些文件加入到自己的工程中編譯、連接,最後生成exe文件。這種代碼級的複用方式存以下的問題
1、c++程序員通常根據自己的需要修改別人提供的代碼。開發者要使用代碼,通常會根據源代碼來理解代碼的意圖。更爲老火的是,還要理解代碼提供者的思路和編碼風格
2、c++代碼級複用導致了硬盤和內存空間的浪費
    假如機器上有n個軟件使用了類CA,在每個軟件的存儲空間中都會有class CA的一份編譯生成的代碼,在這n個軟件同時執行時,會佔用n×sizeof(CA)大小的內存空間
3、軟件一經發布,除非重新編譯整個軟件,否則無法修改
    假如發現了類CA存在一個bug,要修改CA的實現來修復這個bug,那麼就只有重新編譯整個軟件。軟件根本就不具備2進制的模塊化特性。
二、如何解決以上問題————dll的引入
    在window中,一個很好的技術就是動態鏈接庫(dll),有了dll技術,客戶可共享該dll的代碼,這樣在用戶機器上無論有多少個軟件使用該dll,都會只有一份該dll的拷貝。而dll提供給開發者的也只是.h文件,隱藏了代碼的實現細節。
三、dll複用存在的問題
1、編譯器、連接器的不兼容問題
    爲了支持重載,c++編譯器任意修改函數名(名字改編,感興趣的可參考《深入探索c++對象模型第4章——function語意學》),而且每個c++編譯器修改函數名的方法通常都不相同。這個問題的一個解決方案是將函數聲明extern “C”鏈接指示符,這樣做的一個缺陷是:不能用extern “C”聲明成員函數。另一個解決方案是修改DEF文件,這樣可保證所有的編譯器導出相同的函數名,可保證dll在鏈接時的兼容。但這還不能保證2進制結構的兼容性,由於c++標準並未規定程序運行時的狀態,每個編譯器可能有自己的一套處理方式,比如在做異常處理時,一個編譯器拋出的異常,在另一個編譯器中可能不能撲獲到
2、dll致命的弱點——版本衝突問題
    dll的版本問題是臭名昭著的。解決版本衝突問題的經典方法是重命名dll文件名(這也是mfc的解決方案,mfc42d….mfc42ud等)。
四、祭出法寶,面向對象的原則——接口和實現的分離
    dll版本問題的關鍵在於c++的編譯模型和對象之間的緊密耦合關係,c++編譯模型要求客戶需要了解對象的內存佈局,以便爲對象分配內存。該問題的根本解決之道是分離接口和實現。把實現封裝在dll的內部,客戶通過接口來訪問實現。這樣,在客戶代碼中不會包含複用模塊的實現部分。
五、com的解決方案
    com是嚴格分離接口和實現的,客戶只能通過接口來訪問組件的實現。保證了不把任何實現細節暴露給客戶。在客戶使用組件分配內存時,也只有com接口中的vptr指針。Com使用接口繼承的方式分離接口和實現。而大多數編譯器對vptr和vtbl生成的內存佈局是一致的。這樣就解決了編譯器之間的不兼容關係。

com+是在win2k下提出的,在組件服務中配置com組件,該com組件就成了com+,也是windows DNA 的基礎

com+ = com + MTS + MSMQ


發佈了31 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章