網(wǎng)站沒有備案可以做百度推廣嗎關(guān)鍵詞如何確定
首先了解一下com組件,這樣我們才能明白初始化com庫的作用,用到兩個API:CoInitialize,CoInitializEX
一、什么是COM組件
1、COM是Component Object Model (組件對象模型)的縮寫
2、COM組件是以WIN32動態(tài)鏈接庫(DLL)或可執(zhí)行文件(EXE)形式發(fā)布的可執(zhí)行代碼組成。
3、COM組件是遵循COM規(guī)范編寫的
4、COM組件必須是動態(tài)鏈接的
5、COM組件不是一種計算機語言
6、COM組件不是DLL,只是利用DLL來給組件提供動態(tài)鏈接的能力
7、COM組件不是一個API函數(shù)集。
8、COM組件不是類,COM 就是一套接口規(guī)范,就好象交通規(guī)則一樣
9、可以供多種語言調(diào)用,跨語言的調(diào)用
10、COM中的接口是一組由組件實現(xiàn)的提供給客戶使用的函數(shù)。基于二進制接口
《Inside C++ Object Model》
《COM本質(zhì)論》
《COM+技術(shù)內(nèi)幕》
視頻教程:
511遇見易語言模塊API教程
二、認識大漠插件
Dm.dll插件目前是用COM架構(gòu)設(shè)計的,屬于第三方COM對象,要想在我們自己的程序里引用(同進程內(nèi)調(diào)用),需要注冊,或免注冊直接調(diào)用。
大漠綜合插件(dm.dll)采用vc6.0編寫,是一款集前后臺,文字識別,圖色,鍵鼠,窗口,內(nèi)存,DX,Call等功能于一身的綜合插件。主要用于按鍵精靈、簡單游、易語言等輔助制作工具,具有識別速度超級快的特點! 采用COM接口編寫,適用于所有語言調(diào)用。
三、初始化COM
1、CoInitialize
CoInitialize是Windows提供的API函數(shù),用來告訴 Windows以單線程的方式創(chuàng)建com對象。
應(yīng)用程序調(diào)用com庫函數(shù)(除CoGetMalloc(獲取對默認的OLE任務(wù)內(nèi)存分配器指針)和內(nèi)存分配函數(shù))之前必須初始化com庫。
CoInitialize(0)
多線程里創(chuàng)建COM對象前先初始化,一個線程只調(diào)用一次,
CoInitialize(0)
dm.創(chuàng)建 ()
2、CoInitializeEx
是 Windows提供的API函數(shù),為當(dāng)前線程初始化COM庫并設(shè)置并發(fā)模式 。應(yīng)用程序調(diào)用com庫中的函數(shù)(除CoGetMalloc和內(nèi)存分配函數(shù))之前必須初始化com庫。
CoInitializeEx(0,0)
函數(shù)原型
HRESULT CoInitializeEx(
void * pvReserved,
DWORD dwCoInit
);
<strong class="text-danger"> 參數(shù)介紹:</strong>
pvReserved
系統(tǒng) 保留的參數(shù),必須傳入 NULL.
dwCoInit
該標示指明基于當(dāng)前線程的并發(fā)模式和初始化選項。該參數(shù)是 COINIT 枚舉類型,傳入?yún)?shù)時候,除了
COINIT_APARTMENTTHREADED 和COINIT_MULTITHREADED標記外,其余的標記可以組合使用。
在應(yīng)用程序中使用COM庫,至少要調(diào)用一次CoInitializeEx函數(shù)(通常也就調(diào)用一次)。如果傳入?yún)?shù)的并發(fā)標志相同,單個線程也可以多次調(diào)用該函數(shù)
3、CoUninitialize
關(guān)閉當(dāng)前線程的COM庫,卸載線程加載的所有dll,釋放任何其他的資源,關(guān)閉在線程上維護所有的連接。
CoInitialize、CoInitializeEx都是windows的API,主要是告訴windows以什么方式為程序創(chuàng)建COM對象。
有哪些方式呢?單線程和多線程。
CoInitialize指明以單線程方式創(chuàng)建。
CoInitializeEx可以指定以多線程方式創(chuàng)建。
創(chuàng)建單線程方式的COM服務(wù)器時不用考慮串行化問題,多線程COM服務(wù)器就要考慮。
在使用中,使用CoInitialize創(chuàng)建可使對象直接與線程連接,得到最高的性能。
創(chuàng)建多線程對象可以直接接收所有線程的調(diào)用,不必像單線程那樣需要消息排隊,但卻需要COM創(chuàng)建線程間匯集代理,這樣訪問效率高。
CoInitialize對windows來說可能只是設(shè)置一個標志
CoUninitialize可能只是清除標志。
CoInitialize和CoUninitialize最好在應(yīng)用程序初始化以及退出時調(diào)用,樣例中在構(gòu)造以及析構(gòu)中調(diào)用是不提倡的做法。
當(dāng)調(diào)用CoUninitialize這個函數(shù)的時候,會關(guān)掉其所做的線程。那么如果你的應(yīng)用在運行的時候只有一個進程,而且該進程也僅有一個線程的話,那么調(diào)用該函數(shù)自然會導(dǎo)致整個應(yīng)用的退出。
根據(jù)線程模型劃分,進程內(nèi)COM組件分為四類:Single,Apartment,Free,Both
COM套間類型為兩類:STA和MTA,STA是單線程套間,只能運行一個線程,但是一個進程內(nèi)可以創(chuàng)建多個STA,STA總是與一個線程相關(guān)聯(lián),其中第一次創(chuàng)建的STA通常成為主STA(Main STA);MTA是多線程套間,一個進程內(nèi)只能有一個MTA,但是MTA允許運行多個線程。
一個線程要進入到STA中還是MTA中,是由線程內(nèi)調(diào)用CoInitializeEx函數(shù)的第二個參數(shù)決定的。
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);進入到STA(相當(dāng)于調(diào)用CoInitialize(NULL);)
CoInitializeEx(NULL, COINIT_MULTITHREADED);進入到MTA
注意:在不再需要的時候,調(diào)用CoUninitialize();退出套間,一般CoInitializeEx與CoUninitialize都需要成對調(diào)用,以釋放COM占用的資源。
四、CoInitializeEx 與CoInitialize的區(qū)別
1、多線程崩潰和使用CoInitialize或CoInitializeEX沒有關(guān)系
這里也不能說CoInitializeEX(0,0)更適合易語言,而是更適合高并發(fā)。
因為CoInitializeEX內(nèi)部有鎖機制,效率更慢,而需要用內(nèi)存換效率。
2、多線程和高并發(fā)不是一回事極端高并發(fā)下崩潰
3、所以,在某種環(huán)境下,兩者是一致的。 而高并發(fā)可能讓CoInitialize堵塞了
4、后來的應(yīng)使用CoInitializeEX,但是調(diào)用大量早期的歷史Com庫,是使用的CoInitialize
5、有的時候,高并發(fā)崩潰了,真的沒有辦法,因為那超過了機器的處理能力,只能限制。
雖然我們動不動就多線程的說法,但是,實際上我們的CPU常見的也就是4核心。那么真正在運行的也就是4條線程
所以,線程數(shù)量,不是越多越好的。切換時間片的時間,都夠執(zhí)行很多的代碼了。線程多了反而造成了資源的浪費
如果真的需要1400條線程去運行,那你的確需要CoInitializeEX(0,8)確保安全和使用更多的內(nèi)存
但是,如果只是幾條線程,或者幾十條線程,用CoInitialize可以運行的更快,和少占用資源
MSDN也是推薦CoInitializeEX的,那為啥,還是有人選擇CoInitialize呢,存在即合理的
為什么CoInitialize效率快的,高并發(fā)下反而卡死了,占用資源更多呢?
那是因為,他運行的快,無鎖,使用了更多的CPU資源
所以,2個都是可以的,看自己的應(yīng)用場景取舍。更傾向CoInitialize
但是,如果需要高并發(fā),而客戶機器配置也很強大,也會選擇CoInitializeEX
1、問題的重點是,同一套代碼,用CoInitialize(0)或者CoInitializeEX(0,2)高并發(fā)下程序會崩潰,而用CoInitializeEX(0,0)就不會,測試程序的代碼只有幾行,是易語言開發(fā)者常用的計算js的方式,是精易模塊里大量使用的方式,不管您認為是代碼問題還是易語言本身問題,用CoInitializeEX(0,0)不崩潰是事實,如果一定要說有錯,那么是否可以說CoInitializeEX(0,0)更適合易語言,更適合易語言開發(fā)者?
2、多并發(fā)和多線程不是一回事,線程安全跟是否支持高并發(fā)也不是一回事
3、匯編那個我之前就看了,他實際上說的是 CoInitializeEX(0,2) 等效于 CoInitialize(0)
4、其它國際化的語言并沒有默認使用CoInitialize(0),恰恰相反的是CoInitializeEX在其他編程語言中運用還是比較廣泛的,CoInitializeEX默認的參數(shù)就是CoInitializeEX(0,0),而CoInitialize(0)相當(dāng)于 CoInitializeEX(0,2)
5、只要windows系統(tǒng)沒有崩潰,黑屏或者藍屏,而程序崩潰了,那必然是有原因的,有沖突的,這個沖突的地方并不難找到,任何崩潰的問題是應(yīng)該并且可以得到解決的
CoInitialize、CoInitializeEx都是windows的API,主要是告訴windows以什么方式為程序創(chuàng)建COM對象,原因是程序調(diào)用com庫函數(shù)(除CoGetMalloc和內(nèi)存分配函數(shù))之前必須初始化com庫。
有哪些方式呢?單線程和多線程。
CoInitialize指明以單線程方式創(chuàng)建。
CoInitializeEx可以指定COINIT_MULTITHREADED以多線程方式創(chuàng)建。
創(chuàng)建單線程方式的COM服務(wù)器時不用考慮串行化問題,多線程COM服務(wù)器就要考慮。
在使用中,使用CoInitialize創(chuàng)建可使對象直接與線程連接,得到最高的性能。創(chuàng)建多線程對象可以直接接收所有線程的調(diào)用,不必像單線程那樣需要消息排隊,但卻需要COM創(chuàng)建線程間匯集代理,這樣訪問效率不高。
參考:易語言模塊API制作系列視頻教程
? ? ? ? ? ?易語言模塊API視頻教程線程初始化com庫(CoInitialize)