青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

春暖花開
雪化了,花開了,春天來了
posts - 149,comments - 125,trackbacks - 0

面向對象的思想難以適應這種分布式軟件模型,于是組件化程序設計思想得到了迅速的發展。

按照組件化的程序設計的思想,復雜的應用程序被設計成一些小的,功能單一的組件模塊,這些組件模塊可以運行在同一臺機器上,也可以運行在不同的機器上。

為了實現這樣的應用軟件,組建程序和組建程序之間需要一些極為細致的規范, 只有組件程序遵守了這些共同的規范,然間系統才能正常運行。

為此,OMG和Microsoft分別提出了CORBA(Common Object Request Breaker Architecture)和COM(Component Object model)標準,目前CORBA模型主要應用于UNIX操作系統平臺上,而COM 則主要應用于Microsoft Windows操作系統平臺上。


在COM標準中,一個組件程序也被稱為一個模塊,它可以是一個動態連接庫(DLL), 被稱為進程內組件(in-of-process component)也可以是一個可執行程序(EXE),被稱為進程外組件(out-of-process component).


COM對象是建立在二進制可執行代碼級的基礎上,而C++等語言中的對象是建立在源代碼級基礎上的,因此COM對象是語言無關的。這一特性使用不同編程語言開發的組件對象進行交互成為可能。

在Microsoft Windows系統平臺上,COM技術被應用于系統的各個層次,從底層的COM對象管理到上層的應用程序交互都用到了COM標準。


概述

COM既提出了組件之間進行交互的規范,也提供了實現交互的環境, 因為組件對象之間交互的規范不依賴于任何特定的語言,所以COM也可以是不同語言協作開發的一種標準。


OLE技術以COM規范為基礎,OLE充分發揮了COM標準的優勢,使Windows操作系統上的應用程序具有極強的可交互性。如果沒有OLE的支持,Windows操作系統則會遜色很多。


但是,COM規范并不局限于OLE技術,實際上,OLE技術只是COM的一個應用而已,這幾年,OLE技術在進行網絡互連是顯示出了很大的局限性,而COM則表現出了極強的適應能力。


COM標準包括規范和實現兩大部分,規范部分定義了組件和組件之間通信的機制,這些規范不依賴于任何特定的語言和操作系統,只要按照該規范,任何語言都可以使用; COM標準的實現部分是COM庫,COM庫為COM規范的具體實現提供了一些核心服務。


COM是面對對象的軟件模型,因而對象是他的基本要素之一。類似于C++中對象的概念,對象是某個類(class)的一個實例;而類則是一組相關的數據和功能組和在一起的一個定義。使用對象的應用(或另一個對象)成為客戶,有時也成為對象的用戶。


接口是一組邏輯上相關的函數集合,其函數也被稱為接口成員函數。對象通過接口成員函數為客戶提供各種形式的服務。


在COM模型中,對象本身對于客戶來說是不可見的,客戶請求服務時,只能通過接口進行。每一個接口都由一個128位的全局唯一標識符(GUID,Globally Unique Identifier)來標識。客戶通過GUID獲得接口的指針,在通過接口指針,客戶就可以調用其相應的成員函數。


一般來說,接口是不變的,只要客戶期望的接口在組建對象中還存在,它就可以繼續使用該接口所提供的服務。對象可以支持多個接口,因此對組件對象的升級可通過增加接口的辦法實現,這樣得到的新接口可以不影響老接口的使用。


客戶如何來標識COM對象呢?與接口類似,每個對象也用一個128位GUID來標識,稱為CLSID(class identifier,類標識符或類ID),用CLSID標識對象可以保證(概率意義上)在全球范圍內的唯一性。


只要系統中含有這類COM對象的信息,并包括COM對象所在的模塊文件(DLL或EXE文件)以及COM對象在代碼中的入口點,客戶程序就可以由此CLSID來創建COM對象。


那么客戶怎么使用COM對象所提供的服務呢?客戶獲得的又是什么呢?

實際上,客戶成功創建對象后,它得到的是一個指向對象某個接口的指針,因為COM對象至少實現一個接口,所以客戶就可以調用該接口提供的所有服務。


但是COM對象可以有自己的狀態,正是這種狀態才使客戶感覺到COM對象的存在。如果客戶同時擁有兩個相同CLSID的對象,則兩個對象可以有不同的狀態,客戶完全不必關心COM對象是怎么實現的,以及兩個對象的狀態數據之間有什么關系(數組或者鏈表)。當然,COM對象也可以是無狀態的,這種COM對象以提供功能服務為主,可以用來代替傳統的API函數接口,使得應用程序編程接口更為有序,組織層次性更強。


COM本身除了規范之外,也有實現的部分,其中包括一些核心的系統級代碼,也正是這部分核心代碼,才使得對象和客戶之間可通過接口在二進制代碼級進行交互 。

在Microsoft Windows操作系統環境下,這些庫以.dll文件的形勢存在,其中包括以下內容:

(1) 提供了少量的API函數實現客戶和服務端COM應用的創建過程。在客戶端,主要是一些創建函數;而在服務器端,提供一些對象的訪問支持。

(2) COM通過注冊表查找本地服務器即EXE程序,以及程序名與CLSID的轉換等。

(3) 提供了一些標準的內存控制方法,使應用控制進程中內存的分配。

COM庫一般不在應用程序層實現,而在操作系統層次上實現,因此一個操作系統只有一個COM庫實現。而且COM庫的實現必須依賴于具體的系統平臺,尤其是系統底層的一些標準。

COM庫可以保證所有的組件按照統一的方式進行交互操作,而且它使我們在編寫COM應用時,可以不用編寫為進行COM通信而必需的大量基礎代碼,而是直接利用COM庫提供的API進行編程,從而大大加快了開發的速度。例如,現在COM庫的版本都支持遠程組件即分布式COM,我們不用編寫任何網絡或者RPC(remote procedure call)的代碼,就可以實現在網絡上進行程序之間的通信。


如果我們用面向對象語言來實現COM對象,則很自然可以用類類定義對象。在C語言中,對象的概念可能變成一個邏輯概念,如果兩個對象同時存在,則在接口實現中必須明確知道所進行的操作是針對哪個對象的,這個過程可由COM接口的定義保證。


COM規范使用GUID來標識COM對象的思想源于OSF(Open Software Foundation)采用的UUID(Universallz Unique Identifier), UUID被定義為DCE(Distributed Computing Environment)的一部分,主要用于表識RPC通信的雙方。


除了封裝性和重用性,C++對象還有一個重要特性是多態性。正是C++對象的多態性,才體現了C++語言用類描述事物的高度抽象的特征;COM對象也 具有多態性,但這種多態性需要通過COM對象所具有的接口才能體現出來,就像C++對象的多態性需要通過其(virtual)函數才能體現一樣。


從API到COM接口

假如我們要實現一個字處理應用系統,它需要一個查字典的功能,按照組件化程序設計的方法,自然應該把查字典的功能放到一個組件(.dll)程序中實現。如果以后字典程序的查找算法或者字典庫改變了,只要應用程序和組件之間的接口不變,則新的組件程序仍然可以被應用系統使用。這就是采用組件程序帶來的靈活性。


為了把應用系統和組件程序連接起來,又能使它們協同工作,最簡單的做法就是先定義一組查字典的函數,而且這組函數盡可能一般化,不要加入特定的與字典庫相關的知識。


函數
 功能說明
 
Initialize
 初始化
 
LoadLibrary
 裝入字典庫
 
InsertWord
 插入一個單詞
 
DeleteWord
 刪除一個單詞
 
LookupWord
 查找單詞
 
RestoreLibrary
 把內存中的字典庫存入指定的文件中
 
FreeLibrary
 釋放字典庫
 

平面型的API接口層可以很好地把兩個程序連接起來,但存在以下一些問題:

(1) 當API函數非常多時,使用會非常不方便,需要對函數進行組織。

(2) API函數需要標準化,按照統一的調用方式進行處理,以適應不同的語言編程實現。參數的傳遞順序,參數類型,寒暑返回處理都需要標準化。

COM定義了一套完整的接口規范,不僅可以彌補以上API作為組件借口的不足,還充分發揮了組件對象的優勢,并實現了組件對象的多態性。

接口定義和標識
從技術上講,接口是包含了一組函數的數據結構,通過這組數據結構,客戶代碼可以調用組件對象的功能。接口定義了一組成員函數,這組成員函數是組件對象暴露出來的所有信息,客戶程序利用這些函數或的組件對象的服務。


客戶程序用一個指向接口數據機構的指針來調用接口成員函數。接口指針實際上又指向另一個指針,這第二個指針指向一組函數,稱為接口函數表(虛函數表),接口函數表中每一項為4個字節長的函數指針,每個函數指針與對象的具體實現連接起來。通過這種方式,客戶只要獲得了接口指針,就可以調用到對象的實際功能。


對于一個接口來說,他的虛函數表vtable是確定的,因此接口的成員函數個數是不變的,而且成員函數的先后順序也是不變的;對于每個成員函數來說,其參數和返回值也是確定的。


在一個接口的定義中,所有這些信息都必須在二進制一級確定,不管什么語言,只要能支持這樣的內存結構描述,也就是能夠支持“structure“或“record“類型,并且這種類型能夠包含雙重的指向函數指針表的成員,則它就可以支持接口的描述,從而可以用于編寫COM組件或者使用COM組件。

接口描述語言IDL

COM規范在采用OSF的DCE規范描述遠程調用接口IDL的基礎上,進行擴展形成了COM接口的描述語言。

COM規范使用的IDL接口描述語言不僅可用于定義COM接口,同時還定義了一些常用的數據類型,也可以描述自定義的數據結構,對于接口成員函數,我們可以指定每個參數的類型,輸入輸出特性,甚至支持可變長度的數組的描述。IDL支持指針類型,與C/C++很類似。

Microsoft Visual C++提供了MIDL工具,可以把IDL接口描述文件編譯成C/C++兼容的接口描述頭文件(.h)。

IUnknown的定義(IDL):

interface IUnknown
{

HRESULT QueryInterface([in] REFIID iid, [out] void **ppv);
ULONG AddRef(void);
ULONG Release(void);
}


IUnknown的定義(C++):

class IUnknown
{

Public:
virtual HRESULT _stdcall QueryInterface([in] REFIID iid, [out] void **ppv)=0;
virtual ULONG _stdcall AddRef(void)=0;
virtual ULONG _stdcall Release(void)=0;
}

進程內組件

因為進程內組件和客戶程序運行在同一個進程地址空間中,所以一旦客戶程序與組件程序建立起通信關系之后,客戶程序得到的接口指針指向組件程序中接口的vtable,這個vtable包含了所有成員函數地址,客戶代碼可以直接調用這些成員函數,所以其效率非常高。

因為DLL程序是在運行時刻被客戶裝入到內存中的,所以DLL模塊本身也是獨立的,它并不依賴于客戶程序。

在C++語言中,為了使編制的DLL程序更為通用,一般指定DLL的引出函數使用_stdcall調用習慣,如果使用了_cdecl調用習慣,則有些編程語言環境就不能使用這些DLL程序。C++編譯器為DLL程序的每個引出函數生成了一個修飾名,這些修飾名對于不同的編譯器并不兼容,因此,從通用性角度出發,我們在每個函數定義前加上extern ?C“ 說明符。在Visual C++ 開發環境中,下面的說明語句可以很好的說明一個引出函數:

extern ? C“ int _stdcall MyFunction(int n);

為了編制DLL程序,我們可以按照這樣的步驟:

(1) 創建一個DLL工程

(2) 對每個引出函數,使用extern ? C“說明符,以及_stdcall修飾符,如上面對MyFunction函數的說明。

(3) 按照傳統的編程方法,我們還應該編寫一個DEF文件,用來描述DLL程序的模塊信息。在Win32平臺上,我們可以不使用DEF文件,而是直接在函數說明時使用_declspec(dllexport)說明符,例如:

extern ? C“_declspec(dllexport) int _stdcall MyFunction(int n);

按照這樣的方法建立起來的DLL模塊可以被其他程序調用,因為C++連接器會把所有引出函數的信息連接到最終的目標代碼中。


從客戶程序一方來看,有三個系統函數可用于操作DLL程序,LoadLibrary, GetProcAddress, 和FreeLibrary。


一般地,對于DLL程序的使用過程按照這樣的步驟進行:

首先,客戶程序使用LoadLibrary函數裝入DLL,該函數返回模塊的實例句柄,供以后操作該模塊使用。

然后,客戶程序可以調用GetProcAddress函數獲得DLL中引出的函數的地址,我們既可以按函數的序號(在DEF文件中指定)也可以按函數的名字來獲取引出函數的地址,因為客戶程序和DLL程序在相同的內存地址空間中,所以客戶程序可以直接調用這些引出函數。

最后FreeLibrary,把DLL程序卸出內存,以便釋放資源。


說明:

(1) DLL程序不僅可以引出函數,也可以引出全局變量,因為客戶程序和DLL程序在同一個地址空間,所以,把DLL中的全局變量引出到客戶程序中是有意義的。引用的方法并不復雜,或者把變量名放到DEF文件的EXPORTS部分,并加上DATA選項; 或者在變量說明前面加上_declspec(dllexport)說明符。

(2) DumpBin 通過/Exports選項可以列出DLL程序中的所有被引出的信息。

(3) 客戶程序本身也可以是一個DLL程序,但它一定先被裝入到進程空間中,以便可以調用系統函數操作作為服務程序的DLL模塊。

進程外組件
因為進程外組件程序和客戶程序位于不同的進程空間之中,他們使用不同的地址空間,所以組件和客戶之間的通信必須跨越進程邊界,這就涉及到以下一些問題:

(1) 一個進程如何調用另外一個進程中的函數

(2) 參數如何從一個進程被傳遞到另外一個進程中

Windows平臺上,在不同進程之間進行通信的辦法很多,包括DDE, named pipe,或者共享內存等等,COM采用了LPC(Local Procedure Call)和RPC(Remote Procedure Call)

RegEdit可檢查CLSID子鍵下的COM對象(63頁)
Microsoft Visual C++提供OleView.exe,可列出當前機器上的所有類別信息,以及每一種類別下的組件對象列表。

RegSvr32 D:\DicComp\DictComp.dll

RegSvr32 /u D:\DicComp\DictComp.dll

DLL組件必須有DllRegisterServer和DllUnregisterServer兩個用于注冊的入口函數,才能用RegSvr32注冊。

COM規定,支持自注冊的進程外組件必須支持兩個命令行參數/RegServer和/UnregServer,以便完成注冊或注銷操作。
Class Factory

實際上,客戶程序并不直接調用組件程序的引出函數,它調用COM庫的函數進行組件對象的創建工作,COM庫的創建函數根據注冊表的信息調用組件程序的入口函數來創建組件對象。組件程序需要提供一個標準的入口函數DLLGetObjectClass,用于提供本組程序的組件信息。

Class Factory和DLLGetObjectClass函數
類廠是COM對象的生產基地,COM庫通過類廠創建COM對象; 對應每一個COM類,有一個類廠專門用于該COM類的對象創操作。類廠本身也是一個COM對象,它支持一個特殊的接口:IClassFactory,其定義如下:

Class IClassFactory : public IUnknown

{
virtual HRESULT _stdcall CreateInstance(IUnknown *pUnknownOuter, const IID& iid, void **ppv) = 0;
virtual HRESULT _stdcall LockServer(BOOL bLock) = 0;

};

接口IClassFactory有一個重要的成員函數CreateInstance,用于創建對應的COM對象。因為每個類廠之針對特定的COM類對象,所以CreateInstance成員函數知道該創建什么樣的COM對象。在CreateInstance成員函數的參數中,第一個參數pUnknownOuter用于對象被聚合的情形,沒有聚合設成NULL。IClassFactory的另一個成員函數LockServer用于控制組建的生存周期。

因為類廠本身也是個COM對象,它被用于其它COM對象的創建過程,那么類廠對象又由誰來創建呢?答案是DLLGetClassObject引出函數。DLLGetClassObject函數并不是COM庫的函數,而是由組件程序實現的引出函數,我們先看一下DLLGetClassObject函數的原型:

HRESULT DLLGetClassObject(const CLSID& clsid,
Const IID& iid,
(void **) ppv
);

COM庫在接到對象創建的指令后,它要調進程內組件的DLLGetClassObject函數,由該函數創類廠對象,并返回類廠對象的接口指針,COM庫或者客戶一旦有了類廠的接口指針,它們就可以通過類廠接口IClassFactory的成員函數CreateInstance創建相應的COM對象。

COM庫與類廠的交互(67頁)
在COM庫中,有三個API函數可用于對象的創建,它們分別是CoGetClassObject, CoCreateInstance和CoCreateInstanceEx。通常情況下,客戶程序調用其中之一完成對象的創建,并返回對象的初始接口指針。COM庫與類廠也通過這三個函數進行交互。

posted on 2009-06-22 09:51 Sandy 閱讀(379) 評論(0)  編輯 收藏 引用 所屬分類: 雜項學習
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情欧美激情在线五月| 久久久精品午夜少妇| 国产精品久久久久久久午夜片 | 国产精品尤物| 久久成人综合视频| 欧美成人午夜剧场免费观看| 91久久夜色精品国产网站| 欧美久久综合| 欧美专区在线观看一区| 亚洲国产美国国产综合一区二区| 99精品久久久| 国产一区二区三区久久 | 久久精品国产69国产精品亚洲| 国产在线日韩| 欧美日韩精品一区二区天天拍小说 | 欧美日韩a区| 亚洲永久免费精品| 免费看的黄色欧美网站| 亚洲高清视频一区二区| 国产精品久久久久久妇女6080| 午夜精品999| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲综合色婷婷| 亚洲国产精品成人| 国产偷国产偷精品高清尤物| 欧美精品成人91久久久久久久| 午夜精品电影| 一区二区三区国产精品| 亚洲欧洲精品一区二区三区不卡 | 激情六月婷婷久久| 国产精品看片资源| 欧美日韩精品二区| 欧美成人在线免费观看| 久久久久国色av免费看影院| 午夜精品在线观看| 亚洲直播在线一区| 一区二区三区视频免费在线观看| 亚洲国产精品免费| 欧美www视频在线观看| 久久视频一区二区| 久久精品1区| 久久国产乱子精品免费女| 午夜国产一区| 香蕉av777xxx色综合一区| 亚洲一区久久| 亚洲视频视频在线| 99精品国产高清一区二区| 91久久国产精品91久久性色| 伊人久久综合97精品| 国产在线播放一区二区三区| 国产视频精品免费播放| 国产在线精品成人一区二区三区 | 亚洲一区在线观看视频| 亚洲少妇自拍| 亚洲欧美日韩国产中文| 亚洲欧美日韩国产一区二区| 香蕉久久夜色| 久久久www成人免费精品| 久久久久国产一区二区三区四区 | 亚洲精品中文字| 99re在线精品| 欧美午夜精品一区| 亚洲精品免费在线播放| 亚洲欧洲精品一区二区精品久久久 | 欧美久久成人| 欧美午夜精品久久久久久孕妇| 国产精品久久久一区麻豆最新章节| 国产精品久久久久久久久搜平片| 国产欧美一区二区三区沐欲| 好吊视频一区二区三区四区 | 欧美一区二区三区视频| 老司机亚洲精品| 欧美日韩mp4| 国产欧美日韩一区| 亚洲精选在线| 欧美在线啊v一区| 六月婷婷久久| 99re6这里只有精品视频在线观看| 亚洲天堂av在线免费| 久久成人一区| 欧美人在线视频| 国产午夜精品全部视频在线播放| 在线日韩视频| 中文av一区特黄| 久久久久久有精品国产| 亚洲国产精品电影在线观看| 亚洲最新色图| 久久久久久久综合日本| 欧美精品免费在线| 国产欧美一区二区精品性色| 亚洲美女中文字幕| 久久久久久网站| 亚洲免费观看视频| 亚洲欧美中文在线视频| 久久精品一二三区| 亚洲精品日韩在线观看| 久久www成人_看片免费不卡| 欧美日韩国产在线播放| 国内自拍一区| 亚洲欧美日韩系列| 亚洲第一精品福利| 先锋影音国产一区| 欧美日韩亚洲一区二区| 狠狠干狠狠久久| av成人激情| 免费成人高清| 翔田千里一区二区| 欧美四级电影网站| 亚洲精品乱码| 免费的成人av| 欧美在线免费视屏| 国产精品一区一区三区| 亚洲视频第一页| 欧美国产视频一区二区| 久久久免费精品| 亚洲欧美日韩一区二区在线| 欧美激情视频在线播放| 欧美亚洲一区三区| 国产精品久久久久久av福利软件 | 久久精品女人天堂| 亚洲一区二区四区| 欧美日韩高清在线| 国产精品亚洲一区| 午夜精品久久久久久久99热浪潮| 国产精品激情偷乱一区二区∴| 亚洲九九九在线观看| 久久躁狠狠躁夜夜爽| 亚洲在线观看视频| 国产精品视频久久| 午夜亚洲福利| 一二美女精品欧洲| 国产精品久久久久9999吃药| 99精品欧美一区二区蜜桃免费| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲美女区一区| 欧美久久久久免费| 一区二区三区国产精华| 一本色道久久99精品综合| 欧美日韩视频| 亚洲男人影院| 亚洲一区在线播放| 国产日韩欧美三区| 久久综合中文| 免费日韩成人| 亚洲作爱视频| 在线亚洲一区二区| 国产欧美一区二区精品仙草咪 | 国产综合亚洲精品一区二| 麻豆国产精品一区二区三区 | 亚洲伦理一区| 国产精品久久久久秋霞鲁丝 | 久久不见久久见免费视频1| 精品白丝av| 亚洲黄色一区二区三区| 国产精品v欧美精品v日韩| 欧美一级视频| 蜜臀久久久99精品久久久久久| 日韩午夜av在线| 亚洲午夜国产成人av电影男同| 亚洲欧美日韩精品一区二区| 亚洲女人小视频在线观看| 欧美成人免费播放| 亚洲一区二区视频| 久久九九国产| 欧美在线高清视频| 国内精品视频一区| 精品成人一区| 欧美午夜视频一区二区| 中文在线不卡视频| 久久久久国产精品午夜一区| 有码中文亚洲精品| 欧美成人精品激情在线观看 | 久久精品国产999大香线蕉| 这里只有精品视频| 久久经典综合| 欧美va亚洲va国产综合| 久久久综合激的五月天| 日韩一级二级三级| 亚洲国产精品久久91精品| 欧美日韩精品不卡| 欧美jizzhd精品欧美巨大免费| 亚洲一级高清| 日韩午夜av电影| 亚洲精品综合精品自拍| 免费观看一区| 欧美激情成人在线| 99视频一区| 欧美一级片一区| 久久字幕精品一区| 欧美成年人网站| 牛牛精品成人免费视频| 免费av成人在线| 欧美日韩不卡视频| 国产精品久久久久久久9999| 国产伦精品一区二区三区免费| 国产亚洲精久久久久久| 精品av久久707| 一本到12不卡视频在线dvd| 99精品国产福利在线观看免费| 亚洲国产天堂网精品网站|