---------------------------------------------------
綾誨巶鐨勪綔鐢ㄥ埌搴曟槸浠涔堬紵
灝嗘帴鍙g殑瀹炵幇涓庡鎴蜂嬌鐢ㄥ垎紱誨紑鏉ュ悧錛?/p>
涓嶅敖鐒躲備嬌鐢–oCreateInstance錛屽鎴峰彲浠ュ畬鍏ㄤ笉蹇呯煡閬撶被鍘傜殑瀛樺湪錛岃屽垱寤虹粍浠訛紝鑾峰彇緇勪歡瀹炵幇鐨勬帴鍙e茍浣跨敤銆?/p>
鍗矯OM搴撳彲浠ュ畬鍏ㄦ姏寮綾誨巶鐨勬蹇碉紝鑰屾槸鎻愪緵涓涓繖鏍風殑鍑芥暟鍘熷瀷錛?br>CoCreateObject(REFID rclsid,...,REFID riid,void **ppItf);
鐢ㄦ埛鍦ㄨ皟鐢ㄧ殑鏃跺欏彲浠ュriid鎻愪緵IID_Unknown鎴栬呯壒瀹氫簬璇ュ璞$殑涓涓帴鍙o紝鐩存帴鑾峰彇璇ュ璞$殑IUnknown鎴栫壒瀹氱殑鎺ュ彛鎸囬拡銆?/p>
鍙互鐪嬪埌錛岃繖姝f槸CoCreateInstance鎵浣滅殑浜嬫儏銆?/p>
1 綾誨巶鎻愪緵浜嗛棿鎺ュ垱寤虹被瀵硅薄鐨勬柟寮忥細鐢ㄦ埛鍙互鍏堣幏鍙栧茍鎸佹湁綾誨巶鎺ュ彛鎸囬拡錛岄氳繃璇ユ寚閽堟墍鎸囧悜鐨勭被鍘傛帴鍙e垱寤虹被瀵硅薄銆傞傜敤浜庨渶瑕佸垱寤哄涓紙鎴栭噸澶嶅垱寤猴級綾誨璞$殑鍦版柟錛屽噺灝戜簡姣忔閮借瀹氫綅瀵硅薄搴撳茍鎶婂璞″簱瑁呭叆鍐呭瓨鐨勫紑閿銆?br>2 綾誨巶鎻愪緵浜嗕繚璇佺粍浠跺簱鐣欏湪鍐呭瓨涓嶈鍗歌澆鍑哄幓鐨勫彟涓縐嶆柟娉曪細綾誨巶鎺ュ彛鍑芥暟LockServer銆傜粍浠跺簱緇存姢涓涓簱鑼冨洿璁℃暟鍣紝鍙湁璇ヨ鏁板櫒涓?鏃訛紝緇勪歡搴撴墠鍏佽鑷繁琚嵏杞藉嚭鍐呭瓨銆傦紙涓庢鐩稿錛屽紩鐢ㄨ鏁版槸綾誨璞¤寖鍥寸殑錛岄氳繃璇ョ被瀹炵幇鐨勫悇涓帴鍙f潵緇存姢銆傚鏋滀竴涓被瀵硅薄鐨勫紩鐢ㄨ鏁拌揪鍒?錛岄偅涔堣瀵硅薄鍗犳湁鐨勫唴瀛樺氨琚噴鏀撅紝璇ュ璞′笂鐨勬帴鍙f寚閽堜篃涓嶅啀鏈夋晥銆傦級
闄や簡璋冪敤LockServer閿佸畾緇勪歡搴撲互澶栵紝褰撳垱寤虹殑緇勪歡涓暟澶т簬0鏃訛紝緇勪歡搴撲篃涓嶈兘琚嵏杞姐備篃鍙互璇達紝璋冪敤涓嬈ockServer()鐨勪綔鐢ㄧ浉褰撲簬鍒涘緩浜嗕竴涓粍浠躲?/p>
-----------------------------------------------------------------------
瀹㈡埛涓渚э細
1 浣跨敤涓涓帴鍙i渶瑕佺煡閬撳摢浜涗俊鎭紵
澶囬夛細
鎺ュ彛IID
綾誨璞★紙綾誨巶錛塁LSID錛堟垨ProgID錛?br>鎺ュ彛鍑芥暟鍘熷瀷錛堝弬鏁頒釜鏁幫紝綾誨瀷錛岃繑鍥炲鹼級
瀹炵幇鎺ュ彛緇勪歡鐨勭嚎紼嬫ā鍨嬶紙榪涚▼鍐呫佽繘紼嬪銆佽繙紼嬶級錛?br>綾誨瀷搴搕ypelib淇℃伅錛?/p>
鏈嶅姟涓渚э細
2 瀹炵幇涓涓粍浠跺拰鎺ュ彛浠ヤ緵瀹㈡埛璋冪敤錛岄渶瑕佹彁渚涘摢浜涗笢瑗匡紵
澶囬夛細
鎵鏈夊鎴蜂嬌鐢ㄧ粍浠跺拰鎺ュ彛鎵闇鐨勫唴瀹?br>棰濆鐨勮繕鏈夛細
--------------------------------------------------------------------
涓篸ll娣誨姞.def鏂囦歡涓庣洿鎺ュ湪闇瑕佸鍑虹殑鍑芥暟瀹氫箟澶勬寚瀹歘declspec( dllexport )鏈夊尯鍒悧錛熷鏋滄湁鏄粈涔堝尯鍒紵
鎴戝彂鐜板湪outdll.c涓繖鏍鋒寚瀹氾細
__declspec( dllexport ) HRESULT DllGetClassObject (REFCLSID rclsid, REFIID riid, void **ppv)
浼氫駭鐢熺紪璇戦敊璇細
1>------ Build started: Project: outside, Configuration: Debug Win32 ------
1>Compiling...
1>outdll.c
1>d:\outside-cf\outside\outdll.c(19) : error C2375: 'DllGetClassObject' : redefinition; different linkage
1> c:\program files\microsoft visual studio 8\vc\platformsdk\include\objbase.h(833) : see declaration of 'DllGetClassObject'
1>Build log was saved at "file://d:\outside-cf\outside\Debug\BuildLog.htm"
1>outside - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
c2375鐨勮В閲婃剰鎬濇槸鍑洪敊鐨勫嚱鏁頒嬌鐢ㄧ殑閾炬帴鎸囩ず絎︿笌涔嬪墠澹版槑鐨勪笉鍚屻?br>Compiler Error C2375
'function' : redefinition; different linkage
The function is already declared with a different linkage specifier.
objbase.h涓0鏄庝簡DllGetClassObject()鍑芥暟錛?br>STDAPI DllGetClassObject(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR* ppv);
鑰屼嬌鐢?def鏂囦歡灝辨病鏈夐棶棰樸?/p>
-----------------------------------------------------------------------------
鍒濇鎵ц緇撴灉錛?/p>
闂灝辨槸鎬繪湁涓涓垎閰嶇殑鍐呭瓨娌℃湁閲婃斁錛?/p>
鏍規嵁鎵撳嵃鍑烘潵鐨勫唴瀛樺湴鍧鍙互鍒ゆ柇錛屽簲璇ユ槸鍏堝垱寤虹殑綾誨巶瀵硅薄鐨勫唴瀛樻病鏈夐噴鏀俱?br>媯鏌ヤ唬鐮侊紝main()涓茍娌℃湁蹇樿璋冪敤Release(pCF)閲婃斁綾誨巶瀵硅薄銆傛墦鍗癛elease(pCF)鐨勮繑鍥炲鹼紝鍙戠幇鏄?錛屽嵆鍦ㄧ被鍘傛帴鍙f寚閽堜笂灝戣皟鐢ㄤ簡涓嬈elease錛岄偅涔堬紝絀剁珶鏄摢閲屽皯鐨勫憿錛?/p>
main()鍑芥暟涓湁鍏崇被鍘傚璞″紩鐢ㄨ鏁扮殑鍦版柟灝辨槸CoGetClassObject鍜孯elease錛圕reateInstance璺熺被鍘傝嚜宸辯殑寮曠敤璁℃暟鏃犲叧錛夛紝榪欐槸涓瀵瑰鍔犲紩鐢ㄨ鏁板拰鍑忓皯寮曠敤璁℃暟鐨勫搴旀搷浣滐紝鎵浠?main()涓簲璇ユ病鏈夐棶棰樸?/p>
閭d箞錛屽氨鍙湁鍒涘緩綾誨巶瀵硅薄鐨勬椂鍊欎簡銆備笅闈㈢湅涓涓嬬被鍘傚璞℃槸濡備綍鍒涘緩鐨勩?br>棣栧厛錛宮ain璋冪敤CoGetClassObject錛岃鍑芥暟灝辮皟鐢╠ll涓殑DllGetClassObject銆傜敱浜庢槸絎竴嬈¤皟鐢紙涓嶈冭檻鍏朵粬瀹㈡埛浣跨敤璇ll鐨勬儏鍐碉級錛岀▼搴忔墽琛屽埌CreateClassFactory(...),璇ュ嚱鏁版墽琛屽畬鍚庯紝綾誨巶瀵硅薄鐨勫紩鐢ㄨ鏁版槸1銆?/p>
鐢變簬鍒涘緩鎴愬姛錛屽洜姝ょ戶緇悜涓嬫墽琛屽埌QueryInterface,姝ゆ椂錛岀被鍘傚璞$殑寮曠敤璁℃暟鍙樻垚浜?銆傜劧鍚庯紝DllGetClassObject榪斿洖錛宑om搴撳嚱鏁癈oGetClassObject涔熷簲璇ヨ繑鍥炪傛敞鎰忥紝姝ゆ椂鐨勭被鍘傚璞″紩鐢ㄨ鏁板凡緇忔槸2浜嗭紒
鍥犳錛岄棶棰樺氨鍑哄湪榪欓噷銆俶ain璋冪敤涓嬈oGetClassObject鍚庯紝綾誨巶瀵硅薄鐨勫紩鐢ㄨ鏁版槸2錛岃屼笉鏄垜鎯沖悜涓殑1銆備簬鏄紝鍚庨潰璋冪敤涓嬈elease涔熷氨褰撶劧鏃犳硶閲婃斁鎺夌被鍦哄璞′簡銆?/p>
鎵懼埌浜嗗師鍥狅紝鏀規灝卞緢瀹規槗浜嗐傝繖閲屾垜瑙夊緱闇瑕佹妸DllGetClassObject浣滃涓嬩慨鏀癸細
淇敼鍚庡湪鎵ц錛屽唴瀛橀兘姝e父閲婃斁浜嗐?/p>
-------------------------------------------------------------------------------------------
CreateClassFactory浠g爜璇存槑
鍙互鐪嬪埌錛屼袱琛屼唬鐮佺殑鏁堟灉鏄寮曠敤璁℃暟澧?鍙婂噺1錛岃繖涓よ浠g爜鎵ц鍚庯紝瀵瑰紩鐢ㄨ鏁扮殑褰卞搷浜掔浉鎶墊秷錛岀瓑浜庢病鏈夋敼鍙樺紩鐢ㄨ鏁般傞偅涔堬紝鎶婅繖涓よ鍚屾椂娉ㄩ噴鎺夛紝鏄笉鏄彲浠ュ憿錛?br>鎴戠殑鍥炵瓟鏄細鍦ㄦ湰渚嬩腑鍙互銆傚洜涓鴻繖涓よ浠g爜涔嬮棿鐨凲ueryInterface鎬繪槸鍙互鎵ц鎴愬姛鐨勶紙鍥犱負鏄敤IDD_ClassFactory鏉ヨ皟鐢ㄨ鍑芥暟鐨勶級銆傛墍浠ワ紝鍗充究鎶婅繖涓よ浠g爜鍚屾椂娉ㄩ噴鎺夛紝CreateClassFactory鎵ц緇撴潫鍚庯紝綾誨巶瀵硅薄鐨勫紩鐢ㄨ鏁頒篃澧炰簡1錛屼互鍚庤皟鐢≧elease灝卞彲浠ラ噴鏀炬帀綾誨巶瀵硅薄鍗犵敤鐨勫唴瀛樸?br>浣嗘槸錛屽鏋淐FQueryInterface鐨勪唬鐮佺紪鍐欎腑闄や簡閿欒錛屾瘮濡傦紝鍍忚繖鏍峰啓錛?br>
閭d箞錛岃繖涓よ浠g爜涔嬮棿鐨凲ueryInterface灝變細鎵ц鍑洪敊錛岄偅涔堢被鍘傚璞″崰鐢ㄧ殑鍐呭瓨灝辨案榪滄病鏈夋満浼氶噴鏀句簡銆?br>涔熷氨鏄錛孉ddRef鍜孯elease铏界劧鍦ㄤ綔鐢ㄤ笂瀵瑰紩鐢ㄨ鏁版潵璇寸浉浜掓姷娑堬紝浣哛elease鍑芥暟鎻愪緵浜嗛噴鏀懼璞″唴瀛樼殑鏈轟細錛堝綋寮曠敤璁℃暟涓?鏃訛級錛屽鏋滀笉鎴愬鐨勮皟鐢ㄤ粬浠紝涔熷氨澶卞幓浜嗙鐞嗗璞″唴瀛橈紙閲婃斁瀵硅薄鍗犵敤鐨勫唴瀛橈級鐨勬満浼氥?/p>
---------------------------------------------------------------------------
緇勪歡搴搊utside鏂囦歡璇存槑錛?br> IFoo.h IFoo鎺ュ彛澹版槑
outside.c 緇勪歡瀵硅薄銆両Foo鎺ュ彛瀹炵幇
cf.c 綾誨巶瀵硅薄銆両ClassFactory鎺ュ彛瀹炵幇
outdll.c 緇勪歡搴撳鍑哄嚱鏁板疄鐜?br> outside.def 緇勪歡搴撴ā鍧楀畾涔夋枃浠訛紝瀵煎嚭鍑芥暟澹版槑
outside.reg 緇勪歡搴撴敞鍐屾枃浠?/p>
----------------------------------------------------------------------------
婧愮爜錛?outside-cf
鎶婅鏂囦腑瀹炵幇鐨勪唬鐮佹暣鐞嗘眹鎬誨埌涓涓」鐩腑銆傜洰鍓嶅彧鏄疄鐜板埌涓涓腑闂撮樁孌碉紝閲嶇偣鍦ㄨ鏄嶤OM鎺ュ彛鐨勫疄鐜板師鐞嗭紝榪樻病鏈夊寘鍚被鍘傜殑閮ㄥ垎銆備互鍚庤繕闇闄嗙畫娣誨姞綾誨巶絳夐珮綰у姛鑳姐?/p>
鏂囦歡緇勬垚錛?br>ifoo.h COM鎺ュ彛IFoo,鎺ュ彛ID IID_IFoo 澹版槑鏂囦歡銆?br>outside.c COM鎺ュ彛瀹炵幇銆傝繖閲屽疄鐜癐Foo鐨勬槸涓涓粨鏋勪綋COutside.
util.h 涓浜涘畯瀹氫箟銆佸叏灞鍑芥暟銆佸彉閲忓0鏄庢枃浠躲?br>main.c 絎旇呬負瀹炵幇欏圭洰娣誨姞鐨勬枃浠躲傛彁渚沵ain鍑芥暟銆佸唴瀛樼鐞嗗嚱鏁癆lloc,Free鐨勫疄鐜幫紙灝佽C榪愯搴撳嚱鏁癿alloc鍜宖ree.錛夈佹帴鍙D瀹氫箟銆?/p>
COM鎺ュ彛鍒板簳鏄粈涔堬紵
COM鎺ュ彛鏄竴涓寚鍚戣櫄鍑芥暟琛ㄧ殑鎸囬拡銆傞氳繃榪欎釜鎸囬拡鍙互璁塊棶鍐呭瓨涓煇澶勭殑鍚勪釜鍔熻兘鍧楋紝鎵ц棰勫畾涔夌殑鍔熻兘錛屽畬鎴愮敤鎴風殑浠誨姟銆傝繖浜涘姛鑳藉潡浠ュ嚱鏁扮殑褰㈠紡瀛樺湪錛堟兂涓嶅嚭榪樻湁鍏朵粬褰㈠紡:)錛夊茍琚皟鐢ㄣ傚畠浠湁涓涓叡鍚岀偣錛氶兘鍖呭惈涓涓寚閽堝弬鏁幫紝鎸囧悜榪欎簺鍔熻兘瑕佹搷浣滅殑鏁版嵁鍦板潃銆傚湪C++涓紝榪欎釜鍦板潃灝辨槸瀵硅薄鐨勯鍦板潃錛屼篃灝辨槸綾繪垚鍛樺嚱鏁頒腑闅愬惈鐨則his鎸囬拡銆傚湪C鍑芥暟涓茍娌℃湁榪欑鐜版垚鐨勪究鍒╋紝鍥犳浠g爜瀹炵幇涓湪鎺ュ彛瀹氫箟鏃朵粛浣跨敤浜嗘帴鍙f寚閽堬紙HRESULT (__stdcall * QueryInterface) (IFoo * This, const IID * const, void **)錛夛紝鑰屽湪鎺ュ彛鍑芥暟瀹炵幇鏃舵牴鎹粨鏋勪綋甯冨眬緇撴瀯錛屼粠榪欎釜鎺ュ彛鎸囬拡鎺ㄧ畻寰楀埌瀵硅薄瀹炰緥鎸囬拡銆?/p>
typedef struct IFoo
{
struct IFooVtbl * lpVtbl;
} IFoo;
typedef struct IFooVtbl IFooVtbl;
struct IFooVtbl
{
HRESULT (__stdcall * QueryInterface) (IFoo * This, const IID * const, void **) ;
ULONG (__stdcall * AddRef) (IFoo * This) ;
ULONG (__stdcall * Release) (IFoo * This) ;
HRESULT (__stdcall * SetValue) (IFoo * This, int) ;
HRESULT (__stdcall * GetValue) (IFoo * This, int *) ;
};
COM鎺ュ彛鐨勮姹傦細
姣忎竴涓狢OM鎺ュ彛錛堟寚鍚戠殑铏氬嚱鏁拌〃錛夌殑澶翠笁涓嚱鏁板繀欏繪槸IUnknown鎺ュ彛鐨勫嚱鏁幫細QueryInterface,AddRef鍜孯elease銆傚湪C++涓紝縐頒負浠嶪Unknown鎺ュ彛緇ф壙銆?br>瀵逛簬璋冪敤QueryInterface鍝嶅簲鏌ヨIID_IUnknwon寰楀埌鐨勬帴鍙f寚閽堝鹼紝鍚屼竴涓璞″疄鐜扮殑鎵鏈夋帴鍙e繀欏葷浉鍚屻傝繖鏄垽鏂袱涓狢OM瀵硅薄鏄惁鏄悓涓涓璞$殑鏍囧噯銆?/p>
瀹忓畾涔?#8220;#define IUNK_VTABLE_OF(x) ((IUnknownVtbl *)((x)->lpVtbl))“璇存槑
鍦ㄩ澶勭悊杈撳嚭鏂囦歡main.i涓彲浠ユ壘鍒癐UnknownVtbl鍜孖FooVtbl鐨勫0鏄庯細
typedef struct IUnknownVtbl
{
HRESULT ( __stdcall *QueryInterface )(
IUnknown * This,
const IID * const riid,
void **ppvObject);
ULONG ( __stdcall *AddRef )(
IUnknown * This);
ULONG ( __stdcall *Release )(
IUnknown * This);
} IUnknownVtbl;
struct IUnknown
{
struct IUnknownVtbl *lpVtbl;
};
struct IFooVtbl
{
HRESULT (__stdcall * QueryInterface) (IFoo * This, const IID * const, void **) ;
ULONG (__stdcall * AddRef) (IFoo * This) ;
ULONG (__stdcall * Release) (IFoo * This) ;
HRESULT (__stdcall * SetValue) (IFoo * This, int) ;
HRESULT (__stdcall * GetValue) (IFoo * This, int *) ;
};
璇ュ畯瀹氫箟鐨勪綔鐢ㄥ氨鏄妸IFoo鎺ュ彛涓殑IFooVtbl綾誨瀷鐨勬寚閽堟嬁鍑烘潵錛?x)->lpVtbl)錛夛紝騫跺己鍒惰漿鎹紙(IUnknownVtbl *)錛夋垚IUnknownVtbl銆?br>“寮哄埗杞崲”鐨勭粨鏋滄槸浠涔堝憿錛熸槸鎬庝箞鍋氬埌鐨勫憿錛?br>寰堟槑鏄撅紝緇撴灉灝辨槸寰楀埌鐨勬寚閽堜笉鍐嶆槸IFooVtbl *綾誨瀷錛岃屾槸鍙樻垚浜咺UnknownVtbl *綾誨瀷銆傝嚦浜庡仛娉曪紝緋葷粺搴旇璁板綍姣忎竴涓彉閲忋佽〃杈懼紡鐨勭被鍨嬨傚綋榪涜寮哄埗綾誨瀷杞崲鏃訛紝灝憋紙涓存椂鍦幫級淇敼鍏剁被鍨嬩負杞崲鍒扮殑綾誨瀷銆?br>鍚岀悊錛孮ueryInterface, AddRef, Release瀹忓畾涔変腑鐨?IUnknown *)涔熸槸榪欑鐢ㄦ硶銆?/p>
鍙互鐪嬪埌錛屽畯“IUNK_VTABLE_OF“鐨勪綔鐢ㄦ槸渚涘畯QueryInterface,瀹廇ddRef錛屽畯Release寮曠敤錛屾妸IFooVtbl *綾誨瀷杞崲涓篒UnknownVtbl *綾誨瀷錛屾渶緇堣揪鍒拌皟鐢↖UnknownVtbl涓畾涔夌殑涓変釜QueryInterface,AddRef,Release鍑芥暟銆?/p>
閭d箞錛岃繖縐嶅ぇ璐瑰懆绔犵殑鐩殑鏄粈涔堝憿錛熶負浠涔堜笉浠FooVtbl涓笁涓嚱鏁扮殑瀹氫箟褰㈠紡錛堜笉閫氳繃寮哄埗杞崲鏉ヨ漿鎹㈡垚蹇呴』鐨勭被鍨嬶級錛岀洿鎺ヨ皟鐢↖FooVtbl涓畾涔夌殑鍑芥暟鍛紵铏界劧寮哄埗杞崲鍦ㄥ弬鏁板間笂騫朵笉浼氶犳垚鏀瑰彉錛屾渶緇堣皟鐢ㄧ殑涔熸槸IFooVtbl瀹氫箟鐨勫嚱鏁幫紙FooQueryInterface,FooAddRef,FooRelease錛夈?/p>
涓轟粈涔堜竴瀹氳閫氳繃IUnknown鎺ュ彛鎸囬拡璋冪敤榪欎笁涓嚱鏁板憿錛熶慨鏀筈ueryInterface瀹忓畾涔夊涓嬶細
#define QueryInterface(pif, iid, pintf) \
(((pif)->lpVtbl)->QueryInterface(pif, iid, (void **)(pintf)))
鍗抽氳繃IFoo鎺ュ彛鎸囬拡鏉ヨ皟鐢ㄧ敱IUnknown寮曞叆鐨勫嚱鏁幫紝鏈変粈涔堜笉瀵圭殑鍦版柟鍚楋紵
璇曢獙琛ㄦ槑錛屽皢QueryInterface瀹忓畾涔夊涓嬩篃鍙互緙栬瘧閫氳繃錛屾墽琛岃搗鏉ヤ篃娌℃湁鍑虹幇浠諱綍寮傚父銆?br>#define QueryInterface(pif, iid, pintf) \
(((pif)->lpVtbl)->QueryInterface(pif, iid, (void **)(pintf)))
瀵逛簬IUnknown鎺ュ彛鐨勪笁涓嚱鏁幫紝璋冪敤鏃朵紶閫掔殑鍙傛暟鏄疘Unknown *綾誨瀷錛堣QueryInterface, AddRef, Release瀹忓畾涔夛級錛岃屽嚱鏁板畾涔変腑錛團ooQueryInterface, FooAddRef, FooRelease錛夊0鏄庣殑鍙傛暟鏄疘Foo *綾誨瀷錛岃繖縐嶄笉涓鑷寸殑鎯呭喌鏄庝箞鍑虹幇鐨勶紵榪欑涓嶄竴鑷翠笉浼氭湁闂鍚楋紵
榪欑涓嶄竴鑷寸殑浜х敓鏄敱浜庝粠涓嶅悓鐨勮搴︾湅寰呭紩璧風殑銆傚鏋滀粠IUnknown鎺ュ彛鏉ョ湅錛岄偅涔堟帴鍙e嚱鏁頒腑鐨勭涓涓弬鏁扮被鍨嬪氨鏄疘Unknown *;濡傛灉浠嶪Foo鏉ョ湅錛岄偅涔堢涓涓弬鏁扮殑綾誨瀷灝辨槸IFoo *銆?/p>
榪欑涓嶄竴鑷存у彧鏄拡瀵逛簬緙栬瘧鍣ㄥ浜庣被鍨嬬殑緙栬瘧瑕佹眰鏈夋剰涔夌殑錛屽湪鎺ュ彛瀹炵幇鍙婁嬌鐢ㄦ椂錛屼紶閫掔粰lpVtbl->QueryInterface, lpVtbl->AddRef,lpVtbl->Release鐨勭涓涓弬鏁板湪鍊間笂閮芥槸鐩稿悓鐨勶紝閮芥槸瀹炵幇璇ユ帴鍙g殑鍐呭瓨鍦板潃錛堝湪鏈緥涓槸COutside瀵硅薄鐨勯鍦板潃錛夈?/p>
涓浜涜娉曠幇璞″洖欏?/p>
鍑芥暟鎸囬拡鍙橀噺瀹氫箟銆佽祴鍊煎強璋冪敤銆?br>HRESULT (__stdcall * pQI) (IFoo * This, const IID * const, void **) ;
瀹氫箟涓涓嚱鏁版寚閽堝彉閲弍QI,璇ュ彉閲忔寚鍚?#8220;榪斿洖HRESULT,鍙?涓弬鏁板垎鍒負綾誨瀷IFoo *,const IID * const, void **”鐨勫嚱鏁般?/p>
typedef HRESULT (__stdcall * QIType) (IFoo * This, const IID * const, void **) ;
瀹氫箟涓涓嚱鏁版寚閽堢被鍨嬶紝璇ョ被鍨嬬殑鎸囬拡鎸囧悜“榪斿洖HRESULT,鍙?涓弬鏁板垎鍒負綾誨瀷IFoo *,const IID * const, void **”鐨勫嚱鏁般?/p>
HRESULT __stdcall QueryInterface(IFoo * This, const IID * const, void **) ;//鍑芥暟澹版槑紺轟緥
pQI = 0; // 鍑芥暟鎸囬拡璧嬪鹼紝0琛ㄧず涓嶆寚鍚戜換浣曞嚱鏁般?br>pQI = QueryInterface; // 鍑芥暟鎸囬拡璧嬪鹼紝pQI鎸囧悜QueryInterface銆?br>pQI = &QueryInterface; // 涓庝笂闈㈢瓑浠楓?/p>
QueryInterface(&this->ifoo, riid, ppv); // 浣跨敤鍑芥暟鍚嶇洿鎺ヨ皟鐢?br>pQI(&this->ifoo, riid, ppv); // 鍑芥暟鎸囬拡璋冪敤
(*pQI)(&this->ifoo, riid, ppv); // 絎簩縐嶅嚱鏁版寚閽堣皟鐢ㄦ柟寮?/p>
瀹忓畾涔夈佸睍寮瑙勫垯
瀵逛簬瀹忥紝涓鐩存湁涓縐嶉浘閲岀湅鑺辯殑鎰熻錛屼技涔庡緢闅忔剰錛屾庝箞鏉ラ兘琛岋紝姣斿錛?br>#define AddRef(pif) \
(IUNK_VTABLE_OF(pif)->AddRef((IUnknown *)(pif)))
瀹忓畾涔夊簲璇ユ槸鍙互宓屽鐨勶紝鍗沖畯瀹氫箟鐨?#8220;鍐呭“涓繕鍙互鍖呭惈錛堝祵濂楋級瀹忥紝濡傛湰渚嬶紝“IUNK_VTABLE_OF”灝辨槸宓屽瀹忋傚湪灞曞紑鐨勬椂鍊欙紝灝嗗祵濂楃殑瀹忎篃涓騫跺睍寮錛堟浛鎹㈡垚瀹氫箟鐨勫唴瀹癸級錛岀洿鍒頒笉鍐嶆湁瀹忎負姝€?br>閭d箞灝辨湁涓や釜鐤戦棶錛?br>1銆傚鏋滆宓屽鐨勫畯鍖呭惈錛堢洿鎺ユ垨闂存帴錛夊畾涔夌殑瀹忥紝閭d箞灞曞紑灝辨病瀹屾病浜嗭紝姝誨驚鐜簡銆?br>2銆傚鏋滃畾涔夌殑鍐呭涓湁璺熷畾涔夌殑瀹忓悓鍚嶇殑瀛楃涓詫紙姣斿涓婇潰鐨勪緥瀛怚UNK_VTABLE_OF錛夛紝閭d箞鎬庝箞鍖哄垎榪欏悓鍚嶇殑涓滀笢鏄祵濂楃殑瀹忥紙闇瑕佸睍寮錛夛紝榪樻槸涓鑸殑瀛楃涓詫紙涓嶉渶瑕佸睍寮錛夛紵
鍑芥暟璋冪敤瑙勮寖綰﹀畾銆乵ain鍑芥暟璋冪敤瑙勮寖銆?/p>
涓寮濮嬫妸鍑犱釜鏂囦歡姹囨誨埌欏圭洰閲屾椂錛岀紪璇戦氫笉榪囷紝閿欒鎻愮ず澶ц嚧鎰忔濇槸錛屼笉鑳芥妸涓縐嶈皟鐢ㄨ鑼冪殑鍑芥暟鎸囬拡杞崲鎴愬彟涓縐嶈皟鐢ㄨ鑼冪殑鍑芥暟鎸囬拡銆傚悗鏉ユ妸璋冪敤瑙勮寖鏀逛負 /Gz(__stdcall),緙栬瘧涓猴紙Compile As錛夋敼涓?TC(Compile As C Code)灝卞ソ浜嗐?/p>
鎯蟲潵鏄浜?c鏂囦歡錛岀紪璇戝櫒緙虹渷浣跨敤鐨勬槸__cdecl錛岃孖Foo涓殑鎺ュ彛瀹忓畾涔夊湪win32涓嬪睍寮鎴愪簡__stdcall錛屾墍浠ュ嚭鐜頒簡鐭涚浘銆傝屼嬌鐢?Gz寮哄埗鏈0鏄庤皟鐢ㄨ鑼冪殑鍑芥暟浣跨敤__stdcall錛屽疄鐜板氨涓庡0鏄庝竴鑷翠簡銆?/p>
(size_t)&(((s *)0)->m)
c++紼嬪簭鍛樹篃璁擱兘鐭ラ亾錛岃闂湴鍧“0”澶勭殑鎴愬憳鏄竴澶у繉錛屼細閫犳垚GP銆傜劧鑰岋紝鍙栧湴鍧“0”澶勭殑鎴愬憳鐨勫湴鍧錛屽嵈鏄釜鍚堟硶鐨勬搷浣溿傝櫧鐒跺湴鍧“0”澶勫茍娌℃湁浠涔堝唴瀹癸紝浣嗘槸錛屽鏋滃湪鍦板潃0澶勫瓨鏀句竴涓唴瀹癸紝閭d箞璇ュ唴瀹逛腑鐨勬垚鍛樹篃鏄湁鍦板潃鐨勩傛湰渚嬩腑姝f槸宸у鍦板埄鐢ㄨ繖縐嶆柟娉曪紝浠庢帴鍙e湴鍧璁$畻寰楀嚭瀹炵幇璇ユ帴鍙g殑瀹炰緥鍦板潃錛岃繘鑰岃闂疄渚嬬殑鍐呴儴鍙橀噺銆?br>
------------------------------------------------------------------------------------
2009騫?鏈?鏃?br>闄勪笂婧愮爜錛?a href="http://m.shnenglu.com/Files/gracelee/outside.zip">/Files/gracelee/outside.zip
浠g爜鎵ц緇撴灉錛?br>
The
#ifndef xx #define xx ... #endif
method is to make sure that a header file isn't included more than once from the same c file.
You can not - and normally don't want to - stop multiple c files from including the same header file.
A header file is included because:
1) You have specifically added a line #include "xx" or #include <xx> in the source file. Don't do that unless you want the file to be included :)
2) You are including one header file, that it it's turn (one or more steps away) includes another header file. But a header file should only contain a recursive #include if it really needs that other file for some declarations. Hence, you need to include it.
What does this mean?
If the header file must be seen by multiple source files, you can't use it to allocate global variables, since the linker would then complain about multiple sets of global variables with the same name. This can be solved with the following:
//globals.h #ifndef _GLOBALS_H #define _GLOBALS_H #if defined MAIN #define EXTERN #else #define EXTERN extern #endif ... EXTERN int my_global_variable; #endif // _GLOBALS_H
// main.c
#define MAIN
#include "globals.h"
...
// misc.c #include "globals.h" ...
In this case, only the inclusion in main.c will result in an "allocation" of global variables, because the #define EXTERN will be empty. All other source files that includes "globals.h" will just see the type information for the global variables.
鐢變簬瀹氫箟浜嗘搷浣滅閲嶈澆CDerived::operator long() 鍜孋Base::operator long()錛?9琛屽緱浠ョ紪璇戦氳繃銆傚悓鐞嗭紝瀹氫箟浜咰Base::operator char()錛?1琛屽彲浠ョ紪璇戙?br>
鎵ц緇撴灉涓猴細
CBase constructor()
CDerived constructor()
CDerived::operator long()
CBase::operator long()
lTmp=0
CBase::operator char()
cTmp=a
CDerived destructor()
CBase destructor()
榪欓噷娑夊強鍒扮殑姒傚康涓昏鏈夛細
1 綾繪垚鍛樻搷浣滅閲嶈澆錛堜嬌寰楃敤鎴峰畾涔夌被鍨嬭漿鎹負鍐呭緩綾誨瀷鎴愪負鍙兘銆傚浜庣敤鎴峰畾涔夌被鍨嬩箣闂寸殑杞崲錛岃繕鍙互閫氳繃鏋勯犲嚱鏁扮殑鏂瑰紡榪涜錛?br>2 鑷姩綾誨瀷杞崲銆傝嚜鍔ㄧ被鍨嬭漿鎹㈠彂鐢熺殑鎯呭喌鏈変互涓嬪嚑縐嶏細
鍑芥暟璋冪敤鏃朵紶閫掔殑瀹炲弬綾誨瀷涓庡嚱鏁板0鏄庝腑鎸囧畾鐨勫弬鏁扮被鍨嬩笉鍖歸厤
鍑芥暟榪斿洖鐨勫璞$被鍨嬩笌鍑芥暟澹版槑涓寚瀹氱殑榪斿洖綾誨瀷涓嶅尮閰?br>琛ㄨ揪寮忎腑鎿嶄綔鏁扮殑綾誨瀷涓嶄竴鑷達紙榪欐鏄笂闈緥瀛愪腑鐨勬儏鍐碉級