日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

COM原理及应用之COM特性

發(fā)布時間:2025/4/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 COM原理及应用之COM特性 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、面向?qū)ο笙到y(tǒng)的三個最基本的特性
??? 封裝性、多態(tài)性、重用性。
?
2、COM特性的概述
COM對象的封裝特性是很徹底的,所有的對象狀態(tài)信息必須通過接口才能訪問;而COM的多態(tài)性完全通過接口體現(xiàn)出來,而且,COM分別在三個層次上體現(xiàn)了多態(tài)性:接口成員函數(shù)、單個接口、一組接口(對象類別即 implemented category)。而COM的重用性相對復雜。
?
3、重用性
??? 所謂重用性是指,當一個程序單元能夠?qū)ζ渌某绦騿卧峁┕δ芊諘r,盡可能地重用原先程序單元的代碼,既可以在源代碼一級重用,也可以在可執(zhí)行代碼一級重用。
C++語言的重用性位于源代碼一級,一個類可以繼承于另一個類,從而把父類的功能重用。但對于COM組件則情形有所不同,因為COM是建立在二進制代碼基礎上的標準,所以其重用性也必然建立于二進制代碼一級。
COM重用性是指一個COM對象如何重用已有的COM對象的功能,而不是重復實現(xiàn)老的功能服務。按照COM的標準,實現(xiàn)這種重用性有兩條途徑:包容和聚合。
?
4、包容和聚合
對象B調(diào)用對象A的相應成員函數(shù)實現(xiàn)ISomeInterface接口。因此,對象B的ISomeInterface接口提供的功能可以超過對象A的接口功能,返回結(jié)果也可以不一致。甚至,對象B的接口與對象A的接口不一定相同。一般來說,對象A的生存期包含在對象B的生存期之內(nèi)。

在聚合模型中,被聚合的對象A雖然直接向?qū)ο驜的客戶程序提供功能服務,但它的生存期仍受對象B控制,而且其他的一些行為也受對象B的控制,包括內(nèi)部狀態(tài)初始化、獲取數(shù)據(jù)等等。
為了使聚合能夠順利實現(xiàn),對象A必須能夠適應在被聚合的情況下進行特殊的處理,尤其是接口的QueryInterface成員函數(shù),在被聚合情況下,當客戶請求它所不支持的接口或者IUknown接口時,它必須把控制交給外部對象,由外部對象決定客戶程序的請求結(jié)果。
聚合涉及到聚合對象和被聚合對象雙方的協(xié)作,并不是每個對象都能夠支持聚合特性,但聚合體現(xiàn)了組件軟件真正意義上的重用。而包容的重用性完全建立在客戶/服務器模型相對性的基礎上,實際上也就是客戶程序和組件程序的嵌套關系。這是包容和聚合本質(zhì)的不同。
?
5、委托IUnknown和非委托IUnknown
??? 對象創(chuàng)建函數(shù)CoCreateInstance的第二個參數(shù)pUnknownOuter用于解決聚合中IUnknown接口的問題。當其為NULL時表示正常使用,不為NULL時被聚合使用。內(nèi)部對象實現(xiàn)兩個IUnknown 分別用于這兩種情況:委托IUnknown和非委托IUnknown(delegating unknown和nondelgating unknown)。
??? 按照通常使用方式實現(xiàn)的IUnknown為非委托IUnknown,而委托IUnknown在不同的情況下有不同的行為:當對象被正常使用時,委托 IUnknown把調(diào)用傳遞給對象的非委托IUnknown;當對象被聚合使用時,委托IUnknown把調(diào)用傳遞到外部對象的IUnknown接口,即對象被創(chuàng)建時傳遞進來的pUnkownOuter參數(shù),并且,這時外部對象通過非委托IUnknown對內(nèi)部對象進行控制。委托IUnknown本身不進行任何操作。
??? 因為C++類不支持同時實現(xiàn)兩個IUnknown,所以委托IUnknown和非委托IUnknown不能都使用IUnknown類,但我們可以定義一個新的類。因為COM不是通過類名來識別接口,而是通過vtable來調(diào)用接口成員函數(shù)。
?
6、COM接口調(diào)用的進程透明性
??? 客戶程序創(chuàng)建COM對象具有進程透明特性,不管是進程內(nèi)組件還是進程外組件,客戶程序可以使用一致的方法創(chuàng)建COM對象。對于進程內(nèi)組件,無論是創(chuàng)建過程,還是客戶程序?qū)涌诤瘮?shù)的調(diào)用過程,都可以按照一般的同一進程內(nèi)部函數(shù)調(diào)用的過程來理解組件和客戶之間的交互操作;但對于進程外組件,實際的情形要復雜得多,因為組件程序戶程序擁有不同的進程空間,所以,它們之間所有的交互過程都涉及到進程之間的通信過程。然而,COM客戶程序創(chuàng)建進程外組件程序成功后,它就得到了組件對象的一個接口指針,通過該指針間接調(diào)用組件對象的成員函數(shù),如同調(diào)用本進程內(nèi)的函數(shù)一樣,這正是COM所期望達到的透明效果。
?
7、進程外組件對象與客戶程序之間通信過程
??? 接口指針所指的是本進程中的代理對象(proxy),客戶調(diào)用的是代理對象的成員函數(shù),由代理對象通過跨進程的調(diào)用方法(LPC/RPC)與對象進程中的存根代碼(stub)通信,存根代碼再調(diào)用組件對象成員函數(shù)。函數(shù)返回的順序剛好相反。在這個交互過程中,可以看到,客戶仍然在調(diào)用同一進程內(nèi)的組件對象,而組件對象也被同一進程內(nèi)的客戶調(diào)用,從客戶和組件對象兩個角度絲毫感覺不到進程的邊界,所有跨進程的操作完全由代理對象和存根代碼包攬了。
?
8、列集(marshaling)與散集(unmarshaling)
??? 列集是指客戶進程可以透明地調(diào)用另一進程中的對象成員函數(shù)的一種參數(shù)處理機制。
代理對象用列集手段處理成員函數(shù)的參數(shù),通過列集處理后得到一個數(shù)據(jù)包(數(shù)據(jù)流),然后通過一種跨進程的數(shù)據(jù)傳輸方法,比如共享內(nèi)存方法,甚至是網(wǎng)絡協(xié)議等,當數(shù)據(jù)包傳輸?shù)綄ο筮M程后,存根代碼用散集(unmarshaling,列集的反過程)的方法把數(shù)據(jù)包參數(shù)解譯出來,再用這些參數(shù)去調(diào)用組件對象;當組件對象成員函數(shù)返回后,存根代碼又把返回值和輸出參數(shù)列集成新的數(shù)據(jù)包,并把數(shù)據(jù)包傳到客戶進程中,代理對象接收到數(shù)據(jù)包后,把數(shù)據(jù)包解譯出來再返回給客戶函數(shù),從而完成一次調(diào)用。
?
9、連接
??? 連接是指客戶進程與組件進程的一種依賴關系,簡單地說,客戶程序的一個有效接口指針就代表了一個連接。
??? 連接是在函數(shù)調(diào)用的過程中產(chǎn)生的,最常使用的QueryInterface就是一個很好的例子。
??? 連接是跨進程通信的基礎,新的連接本身也是在其他連接的調(diào)用過程中產(chǎn)生的。
?
10、不同參數(shù)的列集處理
??? 32位整數(shù)只要把4字節(jié)的數(shù)據(jù)順序裝到數(shù)據(jù)包中或者從數(shù)據(jù)包中去出來即可;字符串或者結(jié)構(gòu)類型的數(shù)據(jù)列集過程也可以按此方法處理。
??? 對指針的列集處理過程是:列集時,把指針所指的數(shù)據(jù)裝到數(shù)據(jù)包中;散集時,在進程中分配一塊內(nèi)存,把數(shù)據(jù)包中的數(shù)據(jù)拷貝到內(nèi)存中,所得內(nèi)存的地址即為散集的結(jié)果。
如果函數(shù)的參數(shù)中包含了指向接口的指針,則情形要復雜得多。接口的列集包含了代理對象和存根代碼的創(chuàng)建過程,實際上接口指針的列集過程也包括了連接的創(chuàng)建過程。
?
11、列集過程的兩種實現(xiàn)方式:
??? 自定義列集法(custom marshaling),也稱為基本列集法(basic marshaling architecture)。其列集過程完全由對象自身控制,對象指定其代理對象的CLSID,代理對象控制了其所有接口的列集過程,包括接口參數(shù)的列集和散集,以及代理對象和存根代碼之間的跨進程通信過程。??????
??? 標準列集法(standard marshaling),是由COM提供缺省的代理對象和存根代碼,因為列集過程涉及到操作系統(tǒng)的一些復雜特性的編程,如共享內(nèi)存操作或其他跨進程數(shù)據(jù)傳輸機制,甚至通過網(wǎng)絡協(xié)議傳輸數(shù)據(jù),所以COM提供了缺省的代理和存根代碼以及一套標準的列集方法,可以處理常用數(shù)據(jù)類型的列集和散集,包括指針類型和接口指針類型。
??? 標準列集法的原理以及其列集過程與自定義列集法完全一致,事實上標準列集法是自定義列集法的一個特例。但兩者有一個基本的不同:自定義列集法其列集過程完全由對象自身控制,所以它以整個對象為列集單位,即對象指定的代理對象和存根代碼必須處理對象支持的所有接口;而標準列集法使用COM提供的標準代理對象和存根代碼,實際上該代理對象和存根代碼只是列集過程的管理器,因此,標準列集法是以接口為列集單位,COM提供的很多標準接口,其列集過程已經(jīng)由COM 庫提供了,程序員只需要提供自定義接口的列集代碼即可。
?
12、標準列集的實現(xiàn)
??? COM已經(jīng)提供了缺省的代理對象、存根管理器以及RPC通道,我們只需要實現(xiàn)每個接口的代理/存根模塊。一旦系統(tǒng)中安裝了某個接口的代理/存根程序并正確地進行了注冊,則代理管理器和存根管理器會在需要的時候自動加載接口代理和接口存根。因此,從實現(xiàn)的角度來講,我們的任務就是針對接口實現(xiàn)代理/存根程序。
??? 代理/存根組件是一個DLL程序,除了實現(xiàn)接口代理和接口存根之外,還應該實現(xiàn)相應的類廠,代理/存根組件要求類廠支持IPSFactoryBuffer 接口,通過IPSFactoryBuffer::CreateProcy和IPSFactoryBuffer::CreateStub成員函數(shù)創(chuàng)建接口代理和接口存根對象。接口代理對象支持兩個接口:它本身提供列集特性的接口和IRpcProxyBuffer接口,其中IRpcProxyBuffer接口只有Connect和Disconnect成員函數(shù),被代理管理器用于創(chuàng)建或取消它與RPC通道的連接;它本身提供列集特性的接口的成員函數(shù)接受客戶程序的調(diào)用,并把客戶的調(diào)用參數(shù)放到RPC通道中,然后調(diào)用RPC通道的SendReceive成員函數(shù),函數(shù)返回后,把返回值和輸出參數(shù)解譯出來。這些操作是接口代理對象應該完成的。與此相對應,接口存根只要實現(xiàn)IRpcStubBuffer接口,除了存根管理器所調(diào)用的幾個與RPC通道連接的函數(shù)外,最主要的成員函數(shù)為IRpcStubBuffer::Invoke,RPC通道調(diào)用此函數(shù)以響應客戶進程的SendReceive調(diào)用,Invoke函數(shù)把客戶進程傳遞過來的參數(shù)解譯出來,然后調(diào)用組件對象的接口成員函數(shù),并把返回結(jié)果或者輸出參數(shù)經(jīng)過RPC通道傳回到客戶進程的RPC通道中。
??? 接口代理對象和接口存根對象必須非常小心地處理接口成員函數(shù)的參數(shù),尤其是一些指針或者結(jié)構(gòu)參數(shù),如果成員函數(shù)中包含接口指針類型,則還需要調(diào)用 CoMarshalInterface或者CoUnmarshalInterface函數(shù),以便創(chuàng)建相應的存根或者代理對象。在代理和存根中對參數(shù)的處理必須嚴格一致,否則會發(fā)生不可預料的后果。如果客戶進程和組件進程在同一臺機器上運行,則COM會根據(jù)注冊表中的接口信息,在兩個進程中使用相同的代理/存根程序,所以我們只要保證接口的代理/存根程序中對參數(shù)的列集和散集格式一致,參數(shù)傳遞就不會有問題;但如果客戶與組件程序在兩臺機器上,則不能嚴格保證兩個進程會使用相同的代理/存根程序,那么對參數(shù)的列集和散集最好使用統(tǒng)一的數(shù)據(jù)格式表示,以保證參數(shù)傳遞的正確性。
??? 如果一個進程外組件實現(xiàn)了多個COM接口,那么是否需要為每一個接口實現(xiàn)其代理/存根組件程序呢?在這些接口中,如果它是COM提供的標準接口,或者是 OLE標準接口,則COM或者OLE已經(jīng)提供了其代理/存根程序,我們可以不管這些接口,直接使用即可;如果自定義的接口,則必須自己實現(xiàn)代理/存根程序,并注冊到系統(tǒng)中,然后才能真正使用這些接口。
?
13、自定義接口的代理/存根程序的實現(xiàn)
??? Microsoft提供了MIDL實用工具幫助我們建立自定義接口的代理/存根程序。首先我們使用IDL(接口描述語言)語言建立接口描述文件,然后運行 MIDL工具,它會根據(jù)接口描述文件生成一些C語言源代碼文件,用這些源代碼文件可以創(chuàng)建代理/存根組件程序。它為我們提供了接口代理/存根組件的一種標準實現(xiàn)方法。
??? 用IDL描述接口與C++描述接口有一些相似之處,但IDL是一種平臺無關的標準化描述語言。Win32 SDK提供了所有COM或者OLE標準接口的IDL描述,包括unknown.idl(定義了IUnknown接口),可以在Visual C++的include目錄下找到這些IDL文件。Microsoft的RPC開發(fā)包中包括運行程序MIDL.EXE和接口列集使用的 RpcProxy.h、Unknown.idl和wtypes.idl,以及RPC調(diào)用所需要的靜態(tài)連接庫和動態(tài)連接庫。
??? 一般地,用MIDL程序可以產(chǎn)生實現(xiàn)代理/存根組件程序所需要的所有C語言源代碼文件:***.h為接口說明頭文件;***_p.c為接口代理和存根的實現(xiàn)文件;***_i.c為定義所有GUID描述符的文件;dlldata.c包含代理/存根程序的入口函數(shù)及類廠所需的數(shù)據(jù)結(jié)構(gòu)。
??? 運行NMAKE程序可以生成代理/存根組件程序,在集成開發(fā)環(huán)境中也可以生成。在集成開發(fā)環(huán)境中創(chuàng)建一個工程,并把MIDL生成的源代碼文件的DEF文件加入到工程中,并在編譯選項中加入REGISTER_PROXY_DLL,在連接選項中加入rpcrt4.lib、uuid.lib。
??? COM庫能夠提供代理管理器和存根管理器,并且MIDL又能夠自動生成自定義接口的代理和存根源代碼,但目前,COM庫還不能在運行過程中根據(jù)接口的描述自動生成接口代理和接口存根來處理自定義接口的列集過程。
?
14、MIDL創(chuàng)建自定義接口代理/存根組件程序的過程
(1)????????????? 編寫接口的IDL文件;
(2)????????????? 運行MIDL工具生成相關的源代碼文件;
(3)????????????? 編寫DEF文件;
(4)????????????? 編寫MAK文件;
(5)????????????? 編譯連接得到接口/存根組件程序;
(6)????????????? 運行regsvr32.exe注冊組件程序。
?
17、COM的安全性
??? 安全性不是COM的主要目的,但既然COM是一種平臺獨立的軟件模型,而且提供了跨進程甚至跨網(wǎng)絡的客戶/服務器軟件結(jié)構(gòu),則安全性是不可缺少的保護機制。建立一種適合各種操作系統(tǒng)的安全性機制是不可能的,所以COM規(guī)范也只是提供了安全性機制框架。在Windows平臺上實現(xiàn)的COM版本基本上基于 Windows NT的鑒定服務(authentication service)機制。
?
18、Windows NT安全機制
??? Windows NT作為網(wǎng)絡操作系統(tǒng),具有完全的保護機制,系統(tǒng)的所有資源都是受保護的,這些資源包括文件、外設、進程、線程,甚至同步對象、共享內(nèi)存、注冊表中的鍵等等。所謂受保護是指這些資源與特定的訪問權(quán)限聯(lián)系在一起,當這些資源被訪問時,操作系統(tǒng)要對權(quán)限進行驗證,以便允許訪問或者禁止訪問。
?
19、RPC鑒定的5個層次
(1)????????????? 無鑒定操作即正常的RPC調(diào)用;
(2)????????????? 連接時進行鑒定;


(3)????????????? 每一個接口調(diào)用時進行鑒定
(4)????????????? 對每個請求進行鑒定,并對接收到的數(shù)據(jù)包進行完整性檢驗;
(5)????????????? 進行所有的鑒定并對數(shù)據(jù)包加密。
???
20、COM提供了兩種類型的安全性
??? 激活安全性(activation security),不同于激發(fā)安全性(launch security),包括COM對象如何被安全地啟動、客戶如何與對象建立連接,以及如何保護公共的資源,比如全局運行對象表、系統(tǒng)注冊表等。
??? 調(diào)用安全性(call security),是指在已經(jīng)建立連接的基礎上,客戶調(diào)用組件程序的安全保護問題。
?
21、激活安全性
??? SCM是COM庫中負責找到并啟動組件程序的組件。當客戶向COM庫請求創(chuàng)建新的COM對象或者連接已經(jīng)運行的組件對象時,負責處理請求的正是SCM。因此,激活安全性也通過SCM實現(xiàn)。
??? 激活安全性是進程一級的安全性,即進程中所有的對象和所有對象的成員函數(shù)共享的安全性,它分兩種情況:靜態(tài)安全性和動態(tài)安全性。當SCM接收到激活對象的請求時,它檢查注冊表中安全配置信息,以便滿足合法用戶的請求,這稱為靜態(tài)安全性檢查;另一種情況是,在程序運行過程中設置進程的安全性,這稱為動態(tài)安全性檢查。
??? Windows提供的工具DCOMCNFG.EXE(在控制面板中)可以對組件的安全性進行設置。
?
22、調(diào)用安全性
??? 調(diào)用安全性的實現(xiàn)方法之一是使用IClientDecurity接口,方法二是使用COM提供的API函數(shù)。IClientDecurity是接口代理選擇實現(xiàn)的接口,它的三個主要成員函數(shù):CopyProxy、QueryBlanket和SetBlanket。COM提供了幾個API函數(shù)封裝了接口 IClientDecurity的調(diào)用:CoQueryProxyBlanket、CoSetProxyBlanket和CoCopyProxy。
??? MIDL生成的接口代理對象實現(xiàn)了IClientDecurity接口,并且系統(tǒng)代理管理器也實現(xiàn)了IClientDecurity接口,所以并不需要自己實現(xiàn)IClientDecurity接口。
?
23、Win32線程和COM線程
??? Win32提供兩種線程:UI線程(user-interface thread,也稱為用戶界面線程)和輔助線程(worker thread)
??? 對應于Win32的兩種線程,COM也有兩種線程類型:套間線程(apartment thread)(對應于UI線程)和自由線程(free thread)(對應于輔助線程)。
??? COM線程特性是針對特定的COM對象,而不是針對COM組件程序,所以在同一個COM組件中的不同對象可以運行在不同的線程類型上。
?
24、COM線程的使用
??? (1)進程內(nèi)組件對象
??? 如果一個COM對象運行在一個套間線程中,那么此COM對象與UI線程中的窗口對象有很類似的特性。COM對象屬于創(chuàng)建此對象的套間線程所有。套間線程通過消息控制函數(shù)被自動同步,所以,運行在套間線程中的COM對象,不需要進行同步處理,但套間線程外的客戶的其他線程要訪問此線程只能通過代理/存根實現(xiàn)。
??? 如果一個COM對象運行在一個自由線程中,那么同一進程中的其他線程(即客戶線程)可以直接調(diào)用此對象成員函數(shù),但對象成員函數(shù)必須進行同步處理,以保證其線程安全性。
??? (2)進程外組件對象
??? 如果是進程外組件對象,則不管其運行在套間線程還是自由線程中,客戶調(diào)用必須跨進程,因此調(diào)用始終是間接進行的,所以列集對于進程外組件對象是必須的,而列集的結(jié)果是自動實現(xiàn)同步的,對象成員函數(shù)可以不處理同步。
??? 套間線程中的對象被跨線程調(diào)用時,與跨進程調(diào)用有著類似的特性。所以套間線程有自己的COM庫初始化和終結(jié)過程調(diào)用。
?
25、列集和同步
??? COM對象的不同線程模型影響的主要是列集處理和同步處理。結(jié)果列集處理的調(diào)用總是通過代理和存根間接進行,因此,其效率也自然有所降低,但列集使所有對對象的調(diào)用通過消息循環(huán)中轉(zhuǎn),所以調(diào)用被自動進行同步處理,某一時刻至多只能有一個調(diào)用在進行,所以COM對象不需要進行同步處理,也就是說COM對象可以不是線程安全的(thread-safe)。反過來,不通過列集處理的調(diào)用雖然是直接進行的,效率也比較高,但某一時刻可能會有多個客戶同時調(diào)用,因此,對象必須要進行同步處理,以便保證對象是線程安全的。
?
26、不同線程模型(客戶線程與對象線程的不同組合)對列集和同步的不同要求
??? (1)客戶和對象運行在不同的進程中。客戶調(diào)用進程外組件總是要通過代理和存根,所以列集是必須的。因此,COM自動實現(xiàn)了調(diào)用的同步處理,對象不必進行同步處理。
??? (2)客戶和對象運行在同一個線程中。與對象處于同一線程中的客戶調(diào)用對象總是直接進行的,而且同一線程中的調(diào)用不可能沖突,所以客戶調(diào)用即不需要列集,而且對象也不必進行同步處理。
??? (3)客戶和對象運行在同一個進程中,對象運行在套間線程中,客戶運行在另一個套間線程或自由線程中。因為對象運行在它自己的套間線程中,所以客戶調(diào)用總需要列集處理,COM自動實現(xiàn)同步處理,對象不必考慮同步。COM會自動為我們實現(xiàn)接口指針的列集處理,我們也可以自己對接口指針進行列集處理。
??? (4)客戶和對象運行在同一個進程中,對象運行在自由線程中,客戶運行在另一個套間線程或自由線程中。當客戶調(diào)用自由線程中的對象時,雖然對象被自由線程所創(chuàng)建,但調(diào)用實際上在客戶線程中執(zhí)行,所以客戶對接口的調(diào)用是直接進行的,因此接口列集是不必要的,但對象必須自己處理同步,因為多個客戶有可能同時調(diào)用接口成員函數(shù)。
?
27、套間線程
在套間線程的主函數(shù)中有一個消息循環(huán),而且主函數(shù)必須對COM庫進行初始化。COM在套間線程中創(chuàng)建了一個隱藏的窗口,主函數(shù)的消息循環(huán)負責接收消息并分發(fā)消息(包括客戶對對象的調(diào)用的消息)。
對于運行在套間線程中的COM對象來說,因為這樣的對象只能被此線程訪問,其他的線程只能通過代理/存根調(diào)用接口函數(shù),所以對象可以不必擔心同步問題,但對象仍然需要保護全局變量,因為對象的成員函數(shù)被所有的同類對象所共享,因而函數(shù)有可能會重入。進程內(nèi)組件DLL程序的入口在多線程環(huán)境下有可能被同時訪問到,因此,這些入庫函數(shù)如DllGetClassObject和 DllCanUnliadNow仍然需要進行同步處理,以保證多線程訪問時不會發(fā)生沖突。進一步來講,DLL組件程序的類廠也必須滿足一定的要求,以保證多個線程同時訪問類廠對象時不會引發(fā)沖突問題,尤其當用類廠對象創(chuàng)建多個組件對象時,類廠必須是線程安全的,即內(nèi)部提供了同步處理。使類廠線程安全只需對引用計數(shù)操作進行同步保護即可。
如果套間中的函數(shù)要把接口指針傳給另一個線程,不管此線程是套間線程還是自由線程。列集和散集是必須要進行的,列集處理分兩種情況:自動列集和手工列集。自動列集的情況比較簡單,凡是通過COM傳遞的接口指針,COM都會自動列集,包括裝入接口代理和存根代碼等等。手工處理列集也是可能的,因為客戶線程與對象線程在同一個進程中,因此,通過其他途徑傳遞接口指針也很方便。
?
28、自由線程
??? 自由線程在概念上與Win32的輔助線程完全一致。它們只有一個主函數(shù),當主函數(shù)執(zhí)行完成后,線程就自動結(jié)束。在自由線程的主函數(shù)中,必須調(diào)用 CoInitializeEx函數(shù),而且dwCoInit參數(shù)必須指定為COINIT_MULTITHREADED,以便COM知道這是一個自由線程。自由線程中的COM對象必須是線程安全的,所有的同步工作由對象自己處理。
??? 與套間線程類似,自由線程即可以由客戶程序創(chuàng)建,也可以由類廠創(chuàng)建,但不管哪種情況,COM對象總是由自由線程的主函數(shù)來創(chuàng)建。
?
29、進程內(nèi)組件的線程模型
??? 通常進程內(nèi)組件并不調(diào)用CoInitialize或者CoInitializeEx標識其對象所使用的線程模型,但是,COM需要知道進程內(nèi)對象的線程模型,以便正確處理跨線程情況下接口指針的傳遞以及對象調(diào)用的同步處理,所以,我們要在系統(tǒng)注冊表中指定對象的線程模型。
??? 對于進程內(nèi)組件程序,為了支持多線程的情形,不管是套間線程模型還是自由線程模型,其入口函數(shù)DllGetClassObject和DllCanUnloadNow應該是線程安全的,尤其需要對引用計數(shù)包括對象引用計數(shù)器以及鎖計數(shù)器等進行同步保護。
??? 在實際使用過程中,通常對象被客戶線程所創(chuàng)建,因此客戶線程模型與對象的線程模型有可能不一致,這種不一致性包含兩種可能:支持套間線程模型的對象被自由線程所創(chuàng)建,則COM會生成一個套間線程來運行對象,并把列集后的接口指針傳給客戶線程;第二,支持自由線程的對象被套間線程所創(chuàng)建,則COM會生成一個自由線程來創(chuàng)建對象,并把接口指針經(jīng)列集后(可以優(yōu)化)傳給套間線程。
??? 套間線程模型的COM對象,如果用到了自定義接口,則即使是進程內(nèi)組件程


文章出處:http://www.diybl.com/course/3_program/c++/cppxl/20081118/151935.html

轉(zhuǎn)載于:https://www.cnblogs.com/zhangzh/archive/2008/12/11/1353032.html

總結(jié)

以上是生活随笔為你收集整理的COM原理及应用之COM特性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。