COM技術縱橫之談(初學者)

C O M 技術縱橫談 一(轉載)



一:概述

PC機自從誕生以來,硬件經歷了無數變化,CPU從最初的INTEL 8086到
現在PIII滿大街都是也只不過十幾年。微軟的WINDOWS操作系統從最初的
1.0版本到現在即將推出WIN2000,一直是桌面系統上裝機量最大的OS。
作爲軟件開發人員,使用着包括Visual Basic,Visual C++,Delphi包
括最新的Borland C++ builder等等在內的衆多開發環境爲WINDOWS開發
應用程序。應該說現在的開發條件和若干年以前比已經是大大的進步了。
如果你開發過16位的WINDOWS程序,你可能知道爲了讀取一個文件,我
們不得不使用一小段彙編來調用DOS例程,或者使用當時WINDOWS尚未公開
的函數:_lopen()。在win32環境下,你所要做的全部是調用
: :CreateFile()來獲得一個文件句柄,當然如果使用MFC或是OWL之類的
東西,你可以更簡單的做到。不過一般情況下,程序員仍然不得不從頭
開始寫編寫應用程序的每一行代碼。
但這種情況得到了改變:微軟提出了C O M(Component Object Model,
中文也可以譯作"組件對象模型")概念,並且在最新的WINDOWS95/98以
及WIN NT4中越來越廣泛的使用它:我們有理由相信在不久的將來,C O M
將成爲構建應用程序最普遍的方法,如果你對此技術有興趣,不妨參考本
文,希望從中你能學到想知道的知識。如果你已經是C O M老手,也歡迎
你批評指正


本文是針對C++程序員寫的。在介紹概念的時候,我儘量不把WIN32 API
的知識混合進來,以便你能夠更清晰的看到C O M的本質。所有的例子都
用Microsoft Visual C++5(SP3)編譯通過。
一般的講,一個應用程序總是由單個的二進制文件組成。在以前,如果
這個程序需要做一些改進,就要修改源代碼,然後編譯,聲稱新的文件,
然後取代原來的文件。現在,我們用一種全新的角度來看問題:把原先一
整個的EXE可執行文件,分割成功能不同,但相對獨立的幾個部分,把他
們拼裝起來,組成程序,組成軟件。在未來程序發佈以後,如果意識到需
要對他進行修改,只要替換有問題的或是需要升級的組建就可以了。甚至
可以做到再不影響程序正常運行的情況下替換其中的部件。如果你熟悉
WINDOWS編程,可能會想到:DLL似乎就是你所說的東西:可以動態下,動
態連接。事實上,COM正是充分利用了Win32 DLL的靈活性才得以真正在
Windows平臺上實現的。
這樣做有哪些優點呢?首先:用戶一般希望能夠定製所用的應用程序,
而組件技術從本質上講就是可被定製的,因而用戶可以用更能滿足他們需
要的某個組件來替換原來的那個。其次,由於組件是相對應用程序獨立的
部件,我們可以在不同的程序中使用同一個組件而不會產生任何問題,軟
件的可重用性將大大的得到增強。第三,隨着網絡帶寬及其重要性的提高,
分佈式網絡應用程序毫無疑問的成爲軟件市場上越來越重要的買點。組件
價構可以使得開發這類應用程序的過程得以簡化。
那麼,COM到底是什麼呢?它是一個說明如何建立可動態互變組件的規範。
他定義了一些爲保證能互操作,客戶(一個術語,指需要某種組件的程序)
組件必須遵循的標準,COM規範就是一套爲組件架構設置標準的文檔形
式的規範。COM的發佈形式是:以win32動態鏈接庫(DLL)或者可執行文件
(EXE)的形式發佈的可執行代碼組成。
COM組件是動態連接的,而且COM組件是完全與語言無關的。同時,COM組
件可以以二進制的形式發佈。COM組件還可以在不妨礙老客戶的情況下被升
級成新的版本。
你現在可以認爲,COM所能提供的服務有些類似C++中的類。不過類是基
於源代碼的,COM則不是。不過這裏要澄清一些關於COM的錯誤觀點:首先,
COM不是一種計算機語言。把COM同某種計算機語言(如C++, VB)相比較是
沒有意義的。其次,也不要把DLL和COM做比較,因爲COM技術正是利用了
DLL的動態鏈接能力才得以實現的,而現在一般觀點則認爲,利用DLL動態
鏈接能力最佳的方法是COM。

當然,COM也不是win32 API那樣的一個函數集:它並沒有支持或者提供類
似MoveWindow這樣的函數來對系統進行特定的操作。COM也並不是類似於MFC
那樣的C++類庫。COM給開發人員提供的是一種開發與語言無關的組件庫的
方法,但COM本身並沒有提供任何實現。在一定程度上可以認爲COM是系統
無關的,software AG組織正在開發一系列COM支持系統,有望在不久的將
來,包括從Mac OS,VMS,SCO UNIX到LINUX的操作系統上都將得以實現COM。
COM的確有一些具體的實現。COM本身要實現一個稱爲COM庫(COM library)
的API,它提供諸如客戶對組件的查詢,以及組件的註冊/反註冊等一系列
服務,一般來說,COM庫由操作系統加以實現,程序員不必關心其實現的細
節。
總體來看,COM提供了編寫組件的一個標準方法。遵循COM標準的組件可
以被組合起來以形成應用程序。至於這些組件是誰編寫的,是如何實現的
並不重要。組件和客戶之間通過"接口"來發生聯繫。

二:什麼是接口

前面已經提到過,COM組件與客戶大家打交道的唯一辦法是通過接口。在

C++的實現中,我們一般用抽象基類來定義接口,然後利用C++類的多重繼

承實現該組件。下面給出一個簡單的示意:

////////////////
// iface.h
////////////////

#ifndef IFACE_H
#define IFACE_H 1

#define interface class

interface IA
{
public:
virtual func1() = 0;
virtual func2() = 0;
};

interface IB
{
public:
virtual func3() = 0;
virtual func4() = 0;
};

#endif
//////--iface.h end--//////

////////////////
// test.c
////////////////

#include "iface.h"

class Ca : public IA, IB
{
public:
Ca(int i) : m_Count(i) {}
virtual func1() { cout << "IA::func1 is " << m_Count * 1 << endl;
}
virtual func2() { cout << "IA::func2 is " << m_Count * 2 << endl;
}
virtual func3() { cout << "IB::func3 is " << m_Count * 3 << endl;
}
virtual func4() { cout << "IB::func4 is " << m_Count * 4 << endl;
}
int m_Count;
};

main()
{
IA* pIa;
IB* pIb;
Ca* pCa = new Ca(2);
pIa = pCa;
pIa -> func1();
pIa -> func2();
pIb -> func3();
pIb -> func4();
delete pCa;
}
//////--test.c end--//////

上例中,定義了IA,IB兩個接口,你可以注意到他們所有的成員函數都

被聲明爲virtual,並且在函數末尾用 = 0 做了結束。類似這樣的函數

我們在C++中稱之爲純虛函數,如果整個的類都由純虛函數組成,那麼

這個類就叫做抽象基類。抽象基類本身由於沒有實體函數與變量,所以

並不分配內存。一般它的用途是爲派生類指定內存結構。打個比方來說,

就好像把房子分割成很多小間,規定以後哪些小間應該放什麼(函數的

實體)但具體的東西則要等派生類來填放。

這裏有一個概念需要說明一下:組件並不是類,上面我們用一個類就實

現了兩組接口,同樣我們也可以用它來實現更多接口。組件本身其實只

是一個接口集及其實現的集合。一個組件可能包含了多個接口,每一個

接口都有各自的實現。

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