Python的擴展接口[2] -> 動態鏈接庫DLL[0] -> 動態鏈接庫及輔助工具
動態鏈接庫 / Dynamic Link Library
目錄
- 動態鏈接庫簡介
- 函數封裝DLL
- 組件對象模型COM
- 如何判斷.dll文件是COM還是DLL
- 輔助工具
1 動態鏈接庫簡介 / DLL Introduction
動態鏈接庫(Dynamic Link Library, DLL),是微軟在Windows操作系統中,實現共享函數庫概念的一種方式,在Windows下,這些庫函數的擴展名可以是.dll/.ocx(ActiveX)/.drv(舊式系統驅動程序),在Linux系統中常常是.so文件。
動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數。函數的可執行代碼位於一個DLL
動態鏈接庫文件,是一種不可執行的二進制程序文件,它允許程序共享執行特殊任務所必需的代碼和其他資源。Windows提供的DLL文件中包含了允許基於Windows的程序在Windows環境下操作的許多函數和資源。一般被存放在電腦的"C:\Windows\System32"目錄下。
一般來說,動態鏈接庫可分為以下兩種,
- 函數封裝DLL,這是一種最常見的動態鏈接庫文件,這種dll文件通常以函數集合的方式封裝,對外以函數API的方式提供接口;
- 組件對象模型COM,是微軟公司為了計算機工業的軟件生產更加符合人類的行為方式開發的一種新的軟件開發技術。
2 函數封裝DLL
這部分可參考鏈接。
3 組件對象模型COM
3.1 關於COM
組件對象模型(Component Object Model, COM),是微軟公司為了計算機工業的軟件生產更加符合人類的行為方式開發的一種新的軟件開發技術。在COM構架下,人們可以開發出各種各樣的功能專一的組件,然後將它們按照需要組合起來,構成復雜的應用系統。
由此帶來的好處是多方面的,可以將系統中的組件用新的替換掉,以便隨時進行系統的升級和定制,可以在多個應用系統中重復利用同一個組件,可以方便的將應用系統擴展
COM是開發軟件組件的一種方法。組件實際上是一些小的二進制可執行程序,它們可以給應用程序,操作系統以及其他組件提供服務。開發自定義的COM組件就如同開發動態的,面向對象的API。多個COM對象可以連接起來形成應用程序或組件系統。並且組件可以在運行時刻,在不被重新鏈接或編譯應用程序的情況下被卸下或替換掉。Microsoft的許多技術,如ActiveX, DirectX以及OLE等都是基於COM而建立起來的。並且Microsoft的開發人員也大量使用COM組件來定制他們的應用程序及操作系統。
3.2 COM與OLE/ActiveX關系
OLE和ActiveX
對象連接與嵌入(Object Linking and Embedding, OLE),簡稱OLE技術,OLE是一種面向對象的技術,利用這種技術可開發可重復使用的軟件組件(COM)。OLE不僅是桌面應用程序集成,而且還定義和實現了一種允許應用程序作為軟件“對象”(數據集合和操作數據的函數)彼此進行“連接”的機制,這種連接機制和協議稱為組件對象模型(Component Object Model),簡稱COM。OLE可以用來創建復合文檔,復合文檔包含了創建於不同源應用程序,有著不同類型的數據,因此它可以把文字、聲音、圖像、表格、應用程序等組合在一起。
ActiveX是一個開放的集成平臺,為開發人員,用戶和 Web生產商提供了一個快速而簡便的在 Interne和Intranet創建程序集成和內容的方法。使用ActiveX,可輕松方便的在Web頁中插入多媒體效果、交互式對象、以及復雜程序,創建用戶體驗相當的高質量多媒體CD-ROM。其主要技術依舊是COM。
OLE/ActiveX/COM三者關系
參考百度百科的解釋,
現在開始闡述ActiveX、OLE和COM的關系。首先,讓大家有一個總體的概念,從時間的角度講,OLE是最早出現的,然後是COM和 ActiveX。從體系結構角度講,OLE和ActiveX是建立在COM之上的,所以COM是基礎。單從名稱角度講,OLE和ActiveX是兩個商標名稱,而COM則是一個純技術名詞,這也是大家更多的聽說ActiveX和OLE的原因。
既然OLE是最早出現的,那麽就從OLE說起,自從 Windows操作系統流行以來,“剪貼板”(Clipboard)首先解決了不同程序間的通信問題(由剪貼板作為數據交換中心,進行復制、粘貼的操作),但是剪貼板傳遞的都是“死”數據,應用程序開發者得自行編寫、解析數據格式的代碼,於是動態數據交換(Dynamic Data Exchange,DDE)的通信協定應運而生,它可以讓應用程序之間自動獲取彼此的最新數據,但是,解決彼此之間的“數據格式”轉換仍然是程序員沈重的負擔。對象的鏈接與嵌入(Object Linking and Embedded,OLE)的誕生把原來應用程序的數據交換提高到“對象交換”,這樣程序間不但獲得數據也同樣獲得彼此的應用程序對象,並且可以直接使用彼此的數據內容,其實OLE是Microsoft的復合文檔技術,它的最初版本只是瞄準復合文檔,但在後續版本OLE2中,導入了COM。由此可見,COM是應OLE的需求而誕生的,所以雖然COM是OLE的基礎,但OLE的產生卻在COM之前。COM的基本出發點是,讓某個軟件通過一個通用的機構為另一個軟件提供服務。COM的第一個使用者卻是OLE2,所以COM與復合文檔間並沒有多大的關系,實際上,後來COM 就作為與復合文檔完全無關的技術,開始被廣泛應用。這樣一來,Microsoft就開始“染指”通用平臺技術。但是COM並不是產品,它需要一個商標名稱。而那時Microsoft的市場專家們已經選用了OLE作為商標名稱,所以使用COM技術的都開始貼上了OLE的標簽。雖然這些技術中的絕大多數與復合文檔沒有關系。Microsoft的這一做法讓人產生這樣一個誤解OLE是僅指復合文檔呢?還是不單單指復合文檔?其實OLE是COM的商標名稱,自然不僅僅指復合文檔。但Microsoft自己恐怕無法解釋清楚,這要花費相當的精力和時間。於是,隨著Internet的發展,在1996年春,Microsoft改變了主意,選擇ActiveX作為新的商標名稱。ActiveX是指寬松定義的、基於COM的技術集合,而OLE仍然僅指復合文檔。當然,ActiveX最核心的技術還是COM。ActiveX和OLE的最大不同在於,OLE針對的是桌面上應用軟件和文件之間的集成,而 ActiveX則以提供進一步的網絡應用與用戶交互為主。
COM地位
到這裏,大家應該對ActiveX、OLE和COM三者的關系有了一個比較明確的認識,COM才是最根本的核心技術,所以下面的重點 COM。讓對象模型完全獨立於編程語言,這是一個非常新奇的思想。這一點從C++和Java的對象概念上,我們就能有所了解。但所謂COM對象究竟是什麽呢?為了便於理解,可以把COM看作是某種(軟件)打包技術,即把它看作是軟件的不同部分,按照一定的面向對象的形式,組合成可以交互的過程和一組支持庫。COM對象可以用C++、Java和VB等任意一種語言編寫,並可以用DLL或作為不同過程工作的執行文件的形式來實現。使用COM對象的瀏覽器,無需關心對象是用什麽語言寫的,也無須關心它是以DLL還是以另外的過程來執行的。從瀏覽器端看,無任何區別。這樣一個通用的處理技巧非常有用。例如,由用戶協調運行的兩個應用,可以將它們的共同作業部分作為COM對象間的交互來實現(當然,OLE復合文檔也能做到)。為在瀏覽器中執行從Web服務器下載的代碼,瀏覽器可把它看作是COM對象,也就是說,COM技術也是一種打包可下載代碼的標準方法(ActiveX控件就是執行這種功能的)。甚至連應用與本機OS進行交互的方法也可以用COM來指定,例如在Windows和Windows NT中用的是新API,多數是作為COM對象來定義的。
COM雖然起源於復合文檔,但卻可有效地適用於許多軟件問題,它畢竟是處在底層的基礎技術。用一句話來說,COM是獨立於語言的組件體系結構,可以讓組件間相互通信。隨著計算機網絡的發展,COM進一步發展為分布式組件對象模型,這就是DCOM,它類似於CORBA的ORB,本文對此將不再做進一步的闡述。通過上面的講述相信大家一定對ActiveX、OLE和COM/DCOM的關系有了一個清楚的了解。
3.3 COM與一般DLL區別
兩者的主要區別可參考鏈接,
DLL是對靜態連接的一種改進,帶來了更細的開發分工,也帶來了很多問題,其中就有二進制如何交互的問題。這個問題當DLL輸出類時更加突出。
COM為解決此問題提出了極負創意的解決方案,不僅如此,更進一步引申,提出了如何跨 網絡的交互。然後,針對internet服務器的開發提出COM+。COM體系中融合了多種經典的設計模式,可以說是一種更加精幹的C++。
兩者的主要區別點在於,
1. COM組件以接口對功能分類,便於組織。DLL特別是大的DLL,函數一大堆,難以組織;
2. COM組件便於升級維護,功能擴充,只需添加接口就行; DLL升級困難,函 數不能隨意改變;
3. COM創建調用有很好的安全性,DLL沒有;
4. COM組件可輕松實現進程間調用,DLL很困難;
5. COM組件可輕松實現分布式調用,DLL不可能,只能在本機調用;
6. COM組件具有封裝、繼承、多態的面向對象特征,DLL只有封裝;
7. COM組件的為基礎,實現了大量功能:ActiveX,OLE等。
3.4 COM註冊
使用命令行工具可以完成對COM組件的註冊,具體步驟如下,
- 開始菜單,輸入cmd打開命令行工具;
- 使用命令regsvr32 + path進行註冊,其中path為註冊dll所在的文件完整路徑及文件名(或cd到所在目錄再進行註冊);
- 若是64位COM,則先cd到syswow64目錄下再進行註冊。
Note:
- 可在cmd中輸入regsvr32 /?來查看可選參數;
- 當提示報錯碼為0x80070005時,為系統權限不足,需要管理員方式運行cmd後,再進行註冊即可成功;
- 當提示報錯找不到註冊入口DllRegisterServer,請確認是否為有效的ocx/dll,則說明該dll可能是函數封裝的普通dll文件;
- 確保註冊文件所在路徑為全英文。
4 如何判斷.dll文件是COM還是DLL
當拿到一個.dll文件時,如何對判斷這是一個普通的DLL文件,還是一個COM組件。一般情況下,文件類型是應該被告知的,但當不知道時,或許可以嘗試以下幾種方法進行判斷。
1. 嘗試註冊dll文件,若註冊成功則說明是COM(ActiveX/OLE),普通封裝函數的DLL無需註冊即可使用,在註冊時會提示找不到註冊入口;
2. 查看dll文件內部的函數(使用Depends等工具),若顯示的接口函數為特定的五個函數,則基本屬於COM(不排除某些普通DLL實現這些函數的可能):
1) DllMain:入口函數,完成一些Dll初始化工作(DirectShow實現的是DllEntryPoint);
2)DllGetClassObject: 用於獲得類工廠指針;
3)DllCanUnloadNow: 系統空閑時會調用這個函數,以確定是否可以卸載Dll;
4)DllRegisterServer: 將COM組件註冊到註冊表中;
5)DllUnregisterServer: 刪除註冊表中COM組件的註冊信息。
5 輔助工具 / Auxiliary Tools
5.1 Depends
Depends工具可以用來查看dll動態鏈接庫文件,具體使用方法參考鏈接,
在Depends工具中主要界面區域如下,其中,
區域1: Dll的信息窗口,主要顯示程序所需的Dll模塊;
區域2: 所選的Dll模塊所使用的函數,包括序數,提示,函數,入口點等信息;
區域3: 所選的Dll模塊所有的導出函數,同樣包括序數,提示,函數,入口點等信息;
區域4: 所有需要的Dll模塊的屬性,出錯數據會以紅色或黃色提示警告。
5.2 OleViewer
OleViewer可以用於查看當前電腦內安裝的COM組件。
相關閱讀
參考鏈接
http://bbs.csdn.net/topics/380080264
http://www.cnblogs.com/lihaozy/archive/2012/07/04/2576449.html
Python的擴展接口[2] -> 動態鏈接庫DLL[0] -> 動態鏈接庫及輔助工具