Component Object Model (COM) 是什麼?

来源:https://www.cnblogs.com/bitssea/archive/2020/04/30/12590702.html
-Advertisement-
Play Games

本文主要介紹 COM 的基礎知識,傾向於理論性的理解,面向初學者,淺嘗輒止。 1. COM 是什麼: COM 的英文全稱是,Component Object Model,中文譯為,組件對象模型。它官方的概念是:The Microsoft Component Object Model (COM) is ...


本文主要介紹 COM 的基礎知識,傾向於理論性的理解,面向初學者,淺嘗輒止。


1. COM 是什麼:

COM 的英文全稱是,Component Object Model,中文譯為,組件對象模型。它官方的概念是:The Microsoft Component Object Model (COM) is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. 與其說 COM 是 System,更確切的說,應該叫做 Standard。因為它實際上是一套公共的 binary 標準,用於規定 software component 的介面的標準。也有人會把 COM 叫做 Common Object Model,但這其實是一種誤傳,起源於當初一名微軟的工作人員 Mark Ryland[1]

但是,在長期的使用中,大家口中念叨的 COM 漸漸生出了各種各樣的含義,已經不僅僅是最初的含義了。這也是為什麼,對於初學者來說,理解起來特別費勁。因為總會查到層出不窮,又參差不齊的含義,讓人很疑惑到底哪個含義才是標準!

  • 首先,在系統設計上,它是一種,設計理念,
  • 然後,在 Object 的世界中,它是那個世界中的,規範和標準,
  • 再然後,在編程語境下,它是一種,可以調用的,其他程式的介面,
  • 再然後,在實際的電腦文件中,它多數是一個個 DLL 文件,
  • 最後,在內部性質上,它是一個個二進位(Binary)的小程式,

其實在我 Research 的時候,這些概念也是最頭疼的地方。因為對 COM 概念的不瞭解,所以無法區分在不同視角,或者不同角度下的概念。而在 Research 的時候,往往會看到很多不同的網頁,給出各種 COM 的概念。而讓人頭疼的就是,這些概念都不統一,讓人無法理解。甚至開始懷疑,這些網頁真的都是說的同一個東西的概念麽?這種混亂,就是因為,不同的網站,在解釋 COM 的時候,用的是不同的角度。而同一個東西,在不同的角度和情景之下,自然會有不同的含義。所以,往往 COM 到底是什麼,要因情景而視之!但是,上面列出的幾個角度,已足以讓我們對 COM 的概念,構建出一個較為立體的理解了!


2. 科技歷史與 COM 的由來:

要瞭解 COM 的歷史由來,我們首先要從科技發展的歷史開始捋順下來。先說 Object Oriented 這種概念,其實,這種概念據說是19世紀60年代就有了,是源自於 MIT。但是那個時候 PC 還沒有普及,大多數公司使用的都是十分昂貴的大型機,微軟還沒有成立,這種情況下,自然對軟體的需求也是非常基本的,大多數停留在數學計算,文字處理,和軍事使用的範圍。而且那個時候,CPU 的概念都還沒出現,自然電腦也是不可能具備足夠的運算能力的。第一個 CPU,是 Intel 在 1971 年,為完成一家日本公司的訂單而設計發明的,自此才解鎖的計算的巨大潛力,進入了現代電腦的篇章。而 CPU 的發展與成熟,才造就了後來的軟體行業。微軟也於 1975 年正式成立。同年,IBM 也開始生產 Portable Computers。那時起,微型電腦開始變成潮流。Microsoft BASIC 這種最早期的編程語言,也誕生於 1975年。那時候,絕大多數的微型電腦,雖然系統都不同,但是幾乎都支持 BASIC 這種編程語言。正是這種編程語言,成為了日後微軟的基礎。1981年,微軟首次為 IBM 提供了操作系統,叫做 QDOC,是微軟的第一套系統,但卻是買來的,別人研發的系統。1983年,微軟研發出了 Lotus Software,是最早期的電子錶格軟體,這個軟體成為了 IBM 電腦上的明星軟體,裝機必備。後來 1985年 Windows 1 誕生了,同時伴隨著 Microsoft Excel 的誕生。自此之後,軟體行業開始變得日益繁榮,微軟也開啟了自己的軟體帝國。

軟體行業變得日益繁榮,但是 Object Oriented 這種思想,還並沒有發展到一定的高度。那時候,開發個軟體或者系統是非常麻煩,非常複雜的。日後,想給軟體添加一個功能,或者升級一個功能時,就更麻煩,因為,沒辦法獨立的,去更新,或者改進,某一個特定的功能。若想要添加新功能,需要全盤改動後,再重新進行編譯,非常的費時費力。於是人們就開始想辦法解決,上面這個問題,然後 Object Oriented Programming(面向對象的編程)的概念就開始興起。這時,雖然面向對象編程的概念已經興起,但是,還沒有統一的 Framework 或者說是標準,能讓不同軟體之間里的 Object 可以互相交流。於是,不同的軟體,就變成了一個個,孤立在大海中的小島,裡面住著一堆 Objects,無法和外界交流。人們想出的解決辦法就是,開發一個系統或者體系,在這個體系中,寫軟體的人只需要製造出,Software Component 就行了。而,這個 Component 就像是,買回來一個,方塊形的,電子配件一樣,插在我們自己的電路板上,就可以開始發揮作用。而這些,Software Component 外表上,必須遵循系統中的統一標準,而內部,就隨便怎麼編程都可以。後來,微軟在1993年,開發出了這個標準,這標準就被叫做,Component Object Model (COM)。

我們再把 COM 形成前後的,技術發展,掰開來看下。首先,在 1987年,也就是在 Windows 2 發行的時候,Dynamic Data Exchange (DDE) 技術產生了,作為一種進程間通信手段(Inter-process communication)。在這個技術之前,只支持系統和客戶端應用程式之間的通信,這個通信,則是通過 Windows Messaging Layer 實現的。而 DDE 技術,則再此基礎之上,實現了客戶端應用程式之間的通信,這也就成為了進程間通信技術的開端。但這時的通信,還只是停留在 Text conversations 和 Windows messages 的層面上。之後 Antony Williams 分別於 1988年 和 1990年 發表了兩篇微軟內部文章,分別是 【Object Architecture: Dealing With the Unknown】和【On Inheritance: What It Means and How To Use It】。正是兩篇文章奠定了日後 COM 產生的理論基礎。之後,1991年,微軟在 DDE 的基礎上,開發出了第一個 object-based framework(基於對象的框架),叫做 Object Linking and Embedding (OLE),即對象的連接與嵌入。這個技術是同 Word 軟體的發行一同發佈的,專註於實現 Compound document(複合型文件),就是將 Excel 文件,嵌入到 Word 中。同在 1991年,微軟發佈了 Visual Basic 1.0 編程語言,並以 dynamic-link library (DLL) 的形式,附帶了 Visual Basic Extensions (VBX) 插件。這個插件讓使用者,可以通過 Properties and Methods 來操控 objects (對象)。1992年,隨著 Windows 3.1 的發佈,OLE2 和它自己的 Object Model,也一同發佈了。和 OLE1 不同,OLE2 是在 COM 概念的基礎上重新實施的。這時的 COM Application binary interface (ABI),即 COM 應用介面的標準也發生了改變。1994的時候,微軟宣佈,OLE2 改名為 OLE,從此 OLE 變成了,微軟組件技術(Component Technologies)的統稱。同年還發佈了 OLE Custom Controls (OCXs) ,作為 VBX 的升級版。後來,在1995年,微軟發佈了 Visual Basic 4.0,開始支持 OCXs,這時微軟也開始考如何讓 COM 組件可以實現跨語言支持。這就要求,COM 架構下,必須要提供一個一致的介面,以及提供一組可以調用介面內方法的能力。此後,才發展成了我們現今熟悉的 COM 的含義。在1996年,微軟有發現 OCXs 可以應用在瀏覽器上,所以就把部分 OLE 改名為 Internet "ActiveX",然後,逐漸的,所有的 OLE 都改名叫做 ActiveX 了。同年後期,微軟又拓展了 COM 的能力,使得組件對象,擁有了在網路上通信的的能力。這個技術被稱為 DCOM (Distributed COM)。自此便形成了今時今日的 COM 的概念。

這篇文章中涉及到了不少的歷史,之前在學習,近200年的,科技發展歷史時,把 Technology Timeline 寫在博客里,感興趣的同學可以點進去看一下。在那篇博客中,我把微軟技術發展的 Timeline,和科技發展的 Timeline 揉合在了一起,這樣能幫助我們感覺到,技術是在伴隨著科技的發展而發展。也可以看到,COM 這種技術理念的產生,是在PC漸漸普及起來,操作系統漸漸成熟,軟體需求逐漸提高之後才有的。所以很多事情的發展,往往都是自然而然的,因為有了需求,才會有相應的發展。COM 的產生,從這個角度說,也是一種必然。因為 COM 實際上,就是一種規範,就像行業規範一樣,行業太小自然不用規範,而規模大了,需求大了,自然會產生規範,所以 COM 的產生是一種必然結果。而技術的發展,既在推進著科技的發展,也受制於現有科技的邊緣。

3. 介面(Interface)周圍的概念:

個人認為,關於 COM,的一切的一切,最後都是為了這個“介面”。因為只有有了“介面”,才算是真正的實現了 Component Object 的理念(或者說,才算是實現了,把 Object 變成 Component 的想法)。因為只有有了“介面”,Component 才能被叫做組件,才能被調用。所以下麵簡單描述下,幾個常見的,圍繞著“介面”的概念:

3.1. API (Application Programming Interface)

API 中文為,應用程式編程介面;很多時候,都被直接叫做 “介面” (Interface)。“介面”是“操作系統” 或 “程式庫”,提供給應用程式的,接入點,讓應用程式能調用,系統某一方面的功能。其主要作用是,讓開發人員,可以輕鬆調用這些功能,而不需要瞭解,到底怎麼做到的,和底層代碼。但是,API 並不是代碼,他只是一個介面,或者說只是一個地址。

3.2. IDL(Interface Defining Language)

IDL 中文為,介面描述語言。它是一種 Specification language(規範語言)。是用來描述,軟體 Component 的 API 的 “規範語言”。與之相比,Programming Language(編程語言)是可以直接運行,用於系統實現的,形式語言。而,“規範語言” 是通常不能直接運行的,而是用於系統分析和設計的,描述語言。然後,這些一段一段的用來描述 Interface 的文字,就被儲存在了 IDL 文件中(文件尾碼就是 “.idl”)。每個這樣的文件裡面都有,一個 header 和一個 body。格式很整齊。

3.3. OLE (Object Linking and Embedding)

OLE 中文為,對象鏈接與嵌入。是能讓應用程式創建,包含不同來源的文檔,的複合文檔技術。OLE 是建立在 COM 理念的基礎之上的。COM 是理論框架,而 OLE 是根據這個框架,實施出來的一套技術。正如之前在,PC Mag 雜質上看到的一個副標題,就很好的詮釋了這種關係型:"COM-the master plan that lets Windows apps interact through OLE.[2]" 一個比較常見的例子就是,把 Excel 表格,整個插入到 Word 文檔中。而這個 Excel Object,就是通過這個 OLE 技術,連接並嵌入(Linking and Embedding)到 Word 中的。但,正如上文所說,後來 OLE 就變成了,微軟組件技術(Component Technologies)的統稱。而,像這樣的一個典型的 OLE 功能(或 OLE 特性),其背後是有一大堆,Interface(介面)作為支持,才得以實現的。

3.4. GUID (Globally Unique Identifier)

GUID 中文為,全局唯一標識符,也被稱為,UUID (Universally Unique Identifier),即,通用唯一識別碼。是一個用於標識信息的,128-bit的,標識符;由一組,32位數的,16進位的,數字組成。數字串,的格式為 8-4-4-4-12 的32個字元;大概長成這樣:550e8400-e29b-41d4-a716-446655440000。GUID 具有全球唯一性,出現重覆的概率幾乎為零。所以才叫做,全局唯一標識符。

3.5. CLSID (Class IDentifier)

CLSID 中文為,類標識符。是一個 GUID,但是,是專門用於,標識 COM class object 的。每一個 OLE Class,都會有一個與之對應的,全球獨一的 CLSID。

3.6. ProgID (PROGrammatic IDentifier)

ProgID 可以翻譯為,程式標識符,或者,編程標識符。通常情況下,每個 CLSID,都會有對應的 ProgID。例如,ProgID 是 Msxml2.DOMDocument 的字元串;而 CLSID 則長成這個樣子 {F9043C85-F6F2-101A-A3C9-08002B2F49FB}。所以 ProgID 的存在,是為了編程的時候,方便調用。

3.7. Registry (Windows)

Registry 中文為,註冊表。它是一個 hierarchical database (分層的資料庫)。用於儲存 Windows 系統,或者應用程式的 low-level settings。但並不是,所有的應用程式都選擇把設置,存在註冊表裡。Registry 是從 Windows 3.0,推出 OLE 的時候,開始有的。在那之前,應用程式都是把自己的設置信息存在一個尾碼為“.ini”的文本文件中的。除了設置之外,所有的 OLE Objects 的 CLSID, 也都儲存在這個 Registry 中。感興趣的同學可以去 Regedit.exe 中,這個位置(HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID)看下,所有的 CLSID 都長成什麼樣。而在每個 CLSID 的“文件夾”中,又都會儲存著,這個 Class 的 ProgID 的名字。

4. 調用組件的流程

閱讀到這裡的同學,應該已經對基本的概念有一些瞭解。那麼我們就再來看下,在實際運行中,Component(組件)到底是怎麼被調用的。就用在 Word 裡面插入一張 Bitmap Image 來舉例;當我們在 Word 程式里,點擊插入 Object 的時候,Word 會彈出,插入對象的對話框。然後,程式會立刻開始掃描,系統的 Registry,看哪些 Object 是能夠插入的,然後,把它們都列在你面前,供你選擇。當你選中 Bitmap Image 這個對象後,程式會,立刻調出他的 ProgID 名字,然後,把這個名字,遞給一個叫做 CoCreateInstance 的 OLE Function。再然後,在這個 Function 的內部,就開始了一系列流程。

首先 OLE 會用立刻這個 ProgID(或者 CLSID)去找出與它對應的 Regstry 條目。然後,通過註冊表裡登記的信息,便可以輕易的找到,提供這個“服務”的,應用程式,或者 Component(.exe 或者 .dll)到底住在哪裡。一旦找到了,便可以立刻調用(Invoke)這個 Component,然後創建出,一個 Bitmap 對象的 Instance(這個Instance,似乎也叫做 Interface Pointer)。

這和我們寫代碼的時候是一樣的,在我們要使用某個模塊的功能之前,都是先通過 PorgID 創建一個 Instance(例如,在 VBScript 中,通常是用Set XL = CreateObject("Excel.Application")這樣的語句)。然後通過這個 Instance,和它提供的 Interface(介面),我們就可以開始調用,這個實例的各種屬性和功能了(例如 XL.Workbooks.Open("FilePath"))。

當然,這個流程中省略了很多的細節,想要瞭解具體細節的同學,就去看我“腳註2”中的 Article 吧,這篇文章雖然是1995年的,但是寫的非常的好,非常值得閱讀,尤其是在學習 COM 的同學,這篇文章能很好的提升我們的理解。好吧,這部分就這麼多啦。

5. 篇尾結語:

研究的過程中發現,COM 相關的東西,真的是博大精深,作為一隻小白,也只能是淺嘗輒止了。感謝您花時間閱讀,小白貢獻,語失莫怪。文章中涉及到的歷史並沒有列在這裡的參考閱讀,而是列在了我另一篇叫做 Technology Timeline 的博客里,有需要的同學可以點進去看下 (^_−)☆。

P.S. 為了寫完這篇,關於 COM 的小白文章,真的是有一種,跋山涉水,翻山越嶺的感覺啊 (T^T),希望能對同學們有所幫助....

相關書籍:

  1. 《COM技術內幕》,Dale Rogerson
  2. 《Learning DCOM》,Thuan L. Thai
  3. 《Inside OLE》,Kraig Brockschmidt
  4. 《COM本質論》,Don Box
  5. 《MFC Windows程式設計》,Jeff Prosise
  6. 《Windows XP Under the Hood》,Brian Knittel

參考閱讀:

  1. 組件對象模型_百度百科
  2. Component Object Model - Wikipedia
  3. COM Technical Overview - Win32 apps | Microsoft Docs
  4. The Component Object Model - Win32 apps | Microsoft Docs
  5. COM - Marvin's Blog
  6. PC Mag - Google Books


  1. 詳見《COM本質論》;作者:Don Box;來源:Charlie Kidel 序。 ↩︎

  2. [PC Mag], 21 Nov 1995, Vol. 14, No. 20, ISSN 0888-8507, Article: OLE's Component Object Model ↩︎


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 昨天看群里在討論C 中的string駐留池,炒的火熱,幾輪下來理論一堆堆,但是在證據提供上都比較尷尬。雖然這東西很基礎,但比較好的回答也不是那麼容易,這篇我就以我能力範圍之內跟大家分享一下 一:無處不在的池 開發這麼多年,相信大家對‘池’ 這個概念都耳熟能詳了,連接池,線程池,對象池,還有這裡的駐留 ...
  • 0. 前言 在之前的章節中,大致介紹了C 中的一些基本概念。這篇我們將介紹一下C 的I/O操作,這將也是一個小連續劇。這是第一集,我們先來簡單瞭解一下C 中的I/O框架。 1. 什麼是I/O I/O 的全稱是input/output,翻譯過來就是輸入/輸出。對於一個系統或者電腦來說,鍵盤、U盤、網 ...
  • #include "ioCC2530.h" #define D3 P1_0#define D4 P1_1#define D5 P1_3#define D6 P1_4#define SW1 P1_2 unsigned char count_t = 0; //長定時累計變數unsigned char K ...
  • 一、編寫拆分腳本(splitNginxLog.sh) #!/bin/bash year=`date +%Y` month=`date +%m` day=`date +%d` # 原始日誌路徑 logs_path="/var/log/nginx/sitename.com/" # 日誌備份路徑 logs ...
  • 首先解釋一下 橋接模式:在該模式下,開啟的虛擬機相當於區域網中的一臺物理機,在該虛擬機開啟的服務,區域網的機器可以直接用 虛擬機ip + 埠直接訪問。 NAT模式:就是在宿主機內部的一臺虛機機,公用宿主機的網路。該虛擬機開啟的服務,宿主機可以通過 虛擬機ip + 埠直接訪問,但是區域網的機器無法 ...
  • [TOC] 前言 DDL DDL,中文為數據定義語言,DDL的特點是對資料庫內部的對象進行create(創建)、alter(修改)、drop(刪除)等操作,負責管理資料庫的基礎數據,不涉及對錶中內容的操作和更改。 DCL DCL,中文為數據控制語言,DDL的特點是對資料庫內部的對象grant(用戶授 ...
  • 當安裝alluxio時,出現允許打開的文件數目過小問題: The user limit for number of open files is too small. The current value is 4096. For production use, it should be bigger ...
  • [TOC] MySQL全庫備份腳本 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...