欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
VC知識庫文章 - COM 組件設計與應用(七)——編譯、注冊、調用

一、前言

  上兩回中,咱們用 ATL 寫(xiě)了第一個(gè) COM 組件程序,這回中,主要介紹編譯、注冊和調用方法。示例程序你已經(jīng)下載了嗎?如果還沒(méi)有下載,vc6.0 的用戶(hù)點(diǎn)這里,vc.net 的用戶(hù)點(diǎn)這里。


二、關(guān)于編譯

  2-1 最小依賴(lài)

  “最小依賴(lài)”,表示編譯器會(huì )把 ATL 中必須使用的一些函數靜態(tài)連接到目標程序中。這樣目標文件尺寸會(huì )稍大,但獨立性更強,安裝方便;反之系統執行的時(shí)候需要有 ATL.DLL 文件的支持。如何選擇設置為“最小依賴(lài)”呢?答案是:刪除預定義宏“_ATL_DLL”,操作方法見(jiàn)圖一、圖二。


圖一、在vc6.0中,設置方法


圖二、在 vc.net 2003中,設置方法

  2-2 CRT庫
  如果在 ATL 組件程序中調用了 CRT 的運行時(shí)刻庫函數,比如開(kāi)平方 sqrt() ,那么編譯的時(shí)候可能會(huì )報錯“error LNK2001: unresolved external symbol _main”。怎么辦?刪除預定義宏“_ATL_MIN_CRT”!操作方法也見(jiàn)圖一、圖二。(vc.net 2003 中的這個(gè)項目屬性叫“在 ATL 中最小使用 CRT”)

  2-3 MBCS/UNICODE
  這個(gè)不多說(shuō)了,在預定義宏中,分別使用 _MBCS 或 _UNICODE。

  2-4 IDL 的編譯
  COM 在設計初期,就定了一個(gè)目標:要能實(shí)現跨語(yǔ)言的調用。既然是跨語(yǔ)言的,那么組件的接口描述就必須在任何語(yǔ)言環(huán)境中都要能夠認識。怎么辦?用 .h 文件描述?------ C語(yǔ)言程序員笑了,真方便!BASIC 程序員哭了:-( 因此,微軟使用了一個(gè)新的文件格式---IDL文件(接口定義描述語(yǔ)言)。IDL 是一個(gè)文本文件,它的語(yǔ)言語(yǔ)法比較簡(jiǎn)單,很象C。具體 IDL 文件的講解,見(jiàn)下一回《COM 組件設計與應用(八)之添加新接口》。IDL 經(jīng)過(guò)編譯,生成二進(jìn)制的等價(jià)類(lèi)型庫文件 TLB 提供給其它語(yǔ)言來(lái)使用。圖三示意了 ATL COM 程序編譯的過(guò)程:


圖三、ATL 組件程序編譯過(guò)程

  說(shuō)明1:編譯后,類(lèi)型庫以 TLB 文件形式單獨存在,同時(shí)也保存在目標文件的資源中。因此,我們將來(lái)在 #import 引入類(lèi)型庫的時(shí)候,既可以指定 TLB 文件,也可以指定目標文件;
  說(shuō)明2:我們作為 C/C++ 的程序員,還算是比較幸福的。因為 IDL 編譯后,特意為我們提供了 C 語(yǔ)言形式的接口文件。
  說(shuō)明3:IDL 編譯后生成代理/存根源程序,有:dlldata.c、xxx_p.c、xxxps.def、xxxps.mak,我們可以用 NMAKE.EXE 再次編譯來(lái)產(chǎn)生真正的代理/存根DLL目標文件(注1)。


三、關(guān)于注冊

  情況1:當我們使用 ATL 編寫(xiě)組件程序,注冊不用我們來(lái)負責。編譯成功后,IDE 會(huì )幫我們自動(dòng)注冊;
  情況2:當我們使用 MFC 編寫(xiě)組件程序,由于編譯器不知道你寫(xiě)的是否是 COM 組件,所以它不會(huì )幫我們自動(dòng)注冊。這個(gè)時(shí)候,我們可以執行菜單“Tools\Register Control”來(lái)注冊。
  情況3:當我們寫(xiě)一個(gè)具有 COM 功能的 EXE 程序時(shí),注冊的方法就是運行一次這個(gè)程序;
  情況4:當我們需要使用第三方提供的組件程序時(shí),可以命令行運行“regsvr32.exe 文件名”來(lái)注冊。順便說(shuō)一句,反注冊的方法是“regsvr32.exe /u 文件名”;
  情況5:當我們需要在程序中(比如安裝程序)需要執行注冊,那么:

typedef HRESULT (WINAPI * FREG)();TCHAR szWorkPath[ MAX_PATH ];::GetCurrentDirectory( sizeof(szWorkPath), szWorkPath );	// 保存當前進(jìn)程的工作目錄::SetCurrentDirectory( 組件目錄 );	// 切換到組件的目錄HMODULE hDLL = ::LoadLibrary( 組件文件名 );	// 動(dòng)態(tài)裝載組件if(hDLL){	FREG lpfunc = (FREG)::GetProcAddress( hDLL, _T("DllRegisterServer") );	// 取得注冊函數指針	// 如果是反注冊,可以取得"DllUnregisterServer"函數指針	if ( lpfunc )	lpfunc();	// 執行注冊。這里為了簡(jiǎn)單,沒(méi)有判斷返回值	::FreeLibrary(hDLL);}::SetCurrentDirectory(szWorkPath);	// 切換回原先的進(jìn)程工作目錄
  上面的示例,在多數情況下可以簡(jiǎn)化掉切換工作目錄的代碼部分。但是,如果這個(gè)組件在裝載的時(shí)候,它需要同時(shí)加載一些必須依賴(lài)的DLL時(shí),有可能由于它自身程序的 BUG 導致無(wú)法正確定位???.....還是讓我們自己寫(xiě)的程序,來(lái)彌補它的錯誤吧......誰(shuí)讓咱們是好人呢 ,誰(shuí)讓咱們的水平比他高呢,誰(shuí)讓咱們在 vckbase 上是個(gè)“榜眼”呢......


四、關(guān)于組件調用

  總的來(lái)說(shuō),調用組件程序大概有如下方法:
 
#include 方法IDL編譯后,為方便C/C++程序員的使用,會(huì )產(chǎn)生xxx.h和xxx_i.c文件。我們真幸福,直接#include后就可以使用了
#import 方法比較通用的方法,vc 會(huì )幫我們產(chǎn)生包裝類(lèi),讓我們的調用更方便
加載類(lèi)型庫包裝類(lèi) 方法如果組件提供了 IDispatch 接口,用這個(gè)方法調用組件是最簡(jiǎn)單的啦。不過(guò)還沒(méi)講IDispatch,只能看以后的文章啦
加載ActiveX包裝類(lèi) 方法ActiveX 還沒(méi)介紹呢,以后再說(shuō)啦

  下載示例程序后,請逐項瀏覽使用方法:

示例

方法

簡(jiǎn)要說(shuō)明

1#include完全用最基本的 API 方式調用組件,使大家熟悉調用原理
2#include大部分使用 API 方式,使用 CComBSTR 簡(jiǎn)化對字符串的使用
3#include展示智能指針 CComPtr<> 的使用方法
4#include展示智能指針 CComPtr<> 和 CComQIPtr<> 混合的使用方法
5#include展示智能指針 CComQIPtr<> 的使用方法
6#include展示智能指針的釋放方法
7#importvc 包裝的智能指針 IxxxPtr、_bstr_t、_variant_t 的使用方法和異常處理
8#importimport 后的命名空間的使用方法

  示例程序中都寫(xiě)有注釋?zhuān)堊x者仔細閱讀并同時(shí)參考 MSDN 的函數說(shuō)明。這里,我給大家介紹一下“智能指針”:
  對于操作原始的接口指針是比較麻煩的,需要我們自己控制引用記數、API 調用、異常處理。于是 ATL 提供了2個(gè)智能指針的模板包裝類(lèi),CComPtr<> 和 CComQIPtr<>,這兩個(gè)類(lèi)都在 <atlbase.h> 中聲明。CComQIPtr<> 包含了 CComPtr<>的所有功能,因此我們可以完全用 CComQIPtr<> 來(lái)使用智能接口指針,唯一要說(shuō)明的一點(diǎn)就是:CComQIPtr<> 由于使用了運算符的重載功能,它會(huì )自動(dòng)幫我們調用QueryInterface()函數,因此 CComQIPtr<> 唯一的缺點(diǎn)就是不能定義 IUnknown * 指針。

    // 智能指針 smart pointer,按照匈牙利命名法,一般以 sp 開(kāi)頭來(lái)表示變量類(lèi)型    CComPtr < IUnknown > spUnk;	// 正確    // 假設 IFun 是一個(gè)接口類(lèi)型    CComPtr < IFun > spFun;	// 正確    CComQIPtr < IFun > spFun;	// 正確    CComQIPtr < IFun, &IID_IFun > spFun;	// 正確    CComQIPtr < IUnknown > spUnk;	// 錯誤!CComQIPtr不能定義IUnknown指針
給智能指針賦值的方法:
    CComQIPtr < IFun > spFun;	// 調用構造函數,還沒(méi)有賦值,被包裝的內部接口指針為 NULL        CComQIPtr < IFun > spFun( pOtherInterface );	// 調用構造函數,內部接口指針賦值為    // 通過(guò) pOtherInterface 這個(gè)普通接口指針調用QueryInterface()得到的IFun接口指針        CComQIPtr < IFun > spFun( spOtherInterface ); // 調用構造函數,內部接口指針賦值為    // 通過(guò) spOtherInterface 這個(gè)只能接口指針調用QueryInterface()得到的IFun接口指針        CComQIPtr < IFun > spFun ( pUnknown );	// 調用構造函數,由IUnknown的QueryInterface()得到IFun接口指針        CComQIPtr < IFun > spFun = pOtherInterface;	// = 運算符重載,含義和上面一樣    spFun = spOtherInterface;	// 同上    spFun = pUnknown;	// 同上        pUnknown->QueryInterface( IID_IFun, &sp );	// 也可以通過(guò)QueryInterface賦值        // 智能指針賦值后,可以用條件語(yǔ)句判斷是否合法有效    if ( spFun ){}		// 如果指針有效    if ( NULL != spFun ){}	// 如果指針有效        if ( !spFun ){}		// 如果指針無(wú)效    if ( NULL == spFun ){}	// 如果指針無(wú)效
智能指針調用函數的方法:
    spFun.CoCreateInstance(...);	// 等價(jià)與 API 函數::CoCreateInstance(...)    spFun.QueryInterface(...);	// 等價(jià)與 API 函數::QueryInterface()        spFun->Add(...);	// 調用內部接口指針的接口函數    // 調用內部接口指針的QueryInterface()函數,其實(shí)效果和 spFun.QueryInterface(...) 一樣    spFun->QueryInterface(...);	        spFun.Release();	// 釋放內部的接口指針,同時(shí)內部指針賦值為 NULL    spFun->Release();	// 錯?。?!一定不要這么使用?! ? // 因為這個(gè)調用并不把內部指針清空,那么析構的時(shí)候會(huì )被再次釋放(釋放了兩次)
咳......不說(shuō)了,不說(shuō)了,大家多看書(shū),多看MSND,多看示例程序吧。 寫(xiě)累了:-(

五、小結

  敬請關(guān)注《COM 組件設計與應用(八)》------如何增加 ATL 組件中的第二個(gè)接口


注1:編譯代理/存根,vc6.0 中稍微麻煩,我們在后面介紹“進(jìn)程外組件”和“遠程組件”的時(shí)候再介紹。在 vc.net 2003 下則比較簡(jiǎn)單,因為代理/存根作為單獨的一個(gè)工程項目會(huì )自動(dòng)加到我們的解決方案中了。



最新評論 [發(fā)表評論] [文章投稿]
查看所有評論
推薦給好友
打印

真的辛苦了,
又知道了很多以前沒(méi)有注意的問(wèn)題!^_^ ( ks_gq 發(fā)表于 2005-10-11 13:38:00)
 
老師辛苦了
^_^ ( tfeitian 發(fā)表于 2005-10-4 21:00:00)
 
揚老師文章很好,不過(guò)有這篇中有點(diǎn)說(shuō)錯了
CComQIPtr 能包裝IUnknown
請查看
CComQIPtr<IUnknown,IID_IUnknown>
詳細看atlbase.h里面CComQIPtr里面模板特化的例子。 ( lwkl 發(fā)表于 2005-9-21 13:59:00)
 
說(shuō)來(lái)也巧,最近正好想學(xué)COM就到VCK上問(wèn)各高手有什么好書(shū)推薦,于是就有人告訴我了這個(gè)專(zhuān)欄,看了才發(fā)現真是經(jīng)典,語(yǔ)言幽默,深入淺出,我已經(jīng)把楊老師寫(xiě)的COM教程全打印下來(lái)了,再次謝謝楊老師,叫一聲,老師,你辛苦了. ( wangchengh 發(fā)表于 2005-7-21 0:54:00)
 
總結性發(fā)言:
   楊老師好人?。?!,其實(shí)壇子里與楊老師水平伯仲的人還有不少。但不少人不愿意這樣教人。就會(huì )說(shuō):“這些都是基礎知識,看書(shū)去”;要么說(shuō):“查msdn”,是啊理論上,看書(shū),自學(xué),查msdn什么都能解決,理論上從頭寫(xiě)個(gè)操作系統也行;可是我們這些菜鳥(niǎo)來(lái)壇子的目的是什么?我的答案,不知大家同意不?就是“學(xué)的快點(diǎn)啊”。學(xué)習同樣的內容,有人教,快多了。其實(shí)程序語(yǔ)言就象一層窗戶(hù)紙,會(huì )了不難,難了不會(huì )。學(xué)會(huì )了2+3=5,不等于就一定知道1+1等于幾。
   感謝象楊老師這樣的好人! ( xgw 發(fā)表于 2005-7-20 20:30:00)
 
寫(xiě)的太好了~~~~ ( zhao4992 發(fā)表于 2005-7-20 14:03:00)
 
楊老師, 辛苦了~! ( NeverMindEx 發(fā)表于 2005-7-19 10:39:00)
 
第五節的例子USE1中,ONBUTTON1里的s1,s2是不是也應該釋放???剛學(xué),請老師指教 ( sc123456 發(fā)表于 2005-7-19 8:54:00)
 
^_^,楊老師您辛苦了 ( duckbill_panpan 發(fā)表于 2005-7-18 21:44:00)
 
等不及了,請楊老師加快腳步,哈哈 ( yybhz 發(fā)表于 2005-7-18 14:04:00)
 
.......................................................
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
COM組件設計與應用(十二)
COM調用方法
用WTL構建HTML界面應用程序1
ATL智能指針類(lèi)CComPtr與CComQIPtr解析
BHO編程
VC2008 ATL控件 去掉運行庫依賴(lài)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久