背景:分布式軟件架構下,面向對象難以直接適配,組件化設計應運而生。OMG 推 CORBA,Microsoft 推 COM,分佔 UNIX/Windows 陣營。
| 術語 | 定義 | 關鍵點 |
|---|---|---|
| Interface | 純虛函數集合 (C++ 抽象基類) | 名稱以 I 開頭 (如 IUnknown)、不可變、引用計數管理 |
| CoClass | 實現一組接口的具體類 | COM 對象 = CoClass 實例;非 C++ class 概念 |
| COM Server | 包含 CoClass 的 DLL/EXE | In-proc (DLL) / Local (EXE) / Remote (DCOM) |
| Registration | 向註冊表登記 CLSID/路徑/線程模型 | regsvr32 註冊,反註冊移除 |
| GUID / UUID | 128位全局唯一標識符 | 接口用 IID,類用 CLSID,解決命名衝突 |
| HRESULT | 32位錯誤/成功代碼 | SUCCEEDED/FAILED 宏判斷,錯誤查詢工具可用 |
| IUnknown | 所有接口基礎 | QueryInterface/AddRef/Release 三大方法 |
HRESULT QueryInterface(REFIID riid, void **ppv); // 獲取其他接口指針
ULONG AddRef(); // 增加引用計數
ULONG Release(); // 減少引用計數,歸零自銷毀
規則:獲取接口必須 AddRef,用畢必須 Release,否則洩漏或過早銷毀。
CoInitialize/CoInitializeExCoCreateInstance(CLSID, NULL, CLSCTX, IID, &ptr)pUnk->QueryInterface(IID_Ixxx, (void**)&pXxx)pXxx->Release(),最後 CoUninitialize()HKEY_CLASSES_ROOT\CLSID\{CLSID}
InprocServer32 = "path.dll" // DLL 路徑
ThreadingModel = "Apartment" // 線程模型
ProgID = "MyComponent.Class.1" // 人類可讀名
HKEY_CLASSES_ROOT\Interface\{IID}
ProxyStubClsid32 = "{...}" // 遠程調用存根
COM 以二進制標準 + 接口契約 + 引用計數構建語言無關的組件生態。核心價值:封裝實現細節、實現二進制復用、支撐分布式演化。雖然 .NET/WCF/WinRT 等新技術層出不窮,但 COM 仍是 Windows 系統級開發、Shell 擴展、Office 自動化、DirectX 等領域的基石。理解 COM 原理,有助於掌握現代組件架構的底層邏輯。