COM¹ê²{¹Lµ{ (Âà)
±z¬O²Ä
713ÓÂsÄýªÌ
§@ªÌ¡G§d¼C©ú(foxnt)
«e¨¥
COM¤w¸g¦¨¬°¤@Ó¥²»ÝªºªF¦è¤F¡C¦b§ÚÌ©P³ò¡A¥i¥H»¡³B³B¥Rº¡¤FCOM - ¦pªG§A¬O¦b¨Ï¥ÎWINDOWS¡A¨Ã¦b¨ä¤U±½s¼gµ{¦¡ªº¸Ü¡CµM¦Ó¡AµL½×§A¬O¥ÎVC¡AÁÙ¬O¨Ï¥ÎDELPHI¶i¦æCOM½sµ{®É¡A¦b¤j¦h¼Æ±¡ªp¤U¡A½sµ{¤u¨ãªºIDE¤w¸g¦V§AÁôÂäFCOMªº¤j³¡¤À¹ê²{¹Lµ{¡A¨Ï±oµ{¦¡®v®Ú¥»¤£»ÝnÁA¸ÑCOM¡A¥u±M¤ßP§Ó¦a¼g¨ä©ÒÃö¤ßªºÅÞ¿è¥N½X¡C³o´N·N¨ýµÛ¡A§Ú̫ܤ֦³¾÷·|¡A¯à°÷´¦¶}COMªº¯«¯µ±¯½¡A¨Ó¬Ý¨ì¥¦¤U±¨ì©³¬O¤°»òªF¦è¡C³o¹ï©ó¤@ÓWINDOWSµ{¦¡®v¨Ó»¡¡A¤£¯à¤£¬OÓ¿ò¾Ñ¡C
¦]¦¹¡A¥»¤åªº©v¦®¡A´N¬O©ß¶}²{¦³ªºIDE´£¨Ñªº¦UºØÂQ¾É¤u¨ã¡A¤Þ¾É¤j®a±q³Ì°ò¥»ªº¦a¤è¤J¤â¡A§¹¾ã¦a±q¤@Ӫťժºµ{¦¡ùØ¡A«Ø¥ß°_¤@ÓCOMµ{¦¡¡A±q¦Ó¹F¨ì¯à°÷¤ñ¸û²M´·¦aÁA¸Ñ¤@ÓCOM¡A¨ì©³¬O¦p¦ó¥Í¦¨¥X¨Ó¨Ã¹ê²{¦bµ{¦¡¤¤¡C
¥»¤å°²³]¡A±z¬O¤@Ó¦³COM½sµ{¸gÅ窺DELPHI/VCµ{¦¡®v¡A¨Ã§Æ±æÁA¸ÑCOMªº°ò¥»¹ê²{¹Lµ{¡C©ó½g´T©M®É¶¡¡A§ÚÌ¥u°Q½×¶iµ{¤ºªºCOM¡]DLL¡^ªº¹ê²{¡A¨Ã¤Þ¾É¤j®a¿Ë¤â«Ø¥ß°_¤@ӳ̲³æªºCOMµ{¦¡¡C
COM¬O¤°»ò¡H
COM¦³¦UºØªí²{§Î¦¡¡A¥i¥H¬O¶iµ{¤º¡A¤]¥i¥H¬O¶iµ{¥~¡F¥i¥H¦b¥»¾÷½Õ¥Î¡A¤]¥i¥H»·ºÝ½Õ¥Î¡C°O±o°ê¥~¦³Ó¬ã¨sCOMªº²Õ´¡A¥Lªº¥DÃD´N¥s§@¡GCOM´N¬O·R¡I ³o·íµM¬O¥~°ê¤Hªº«ÕÀq¡A¥L¥u¬O·Q»¡©ú¡ACOM¬OÓ¦h»ò«nªºªF¦è¡C¨º»òCOM¨ì©³¬OÓ¤°»òªF¦è©O¡H
«Ü¦¥H«e¡A¦b§Úè¶}©l¾Ç²ßCOMªº®ÉÔ¡A¨Ãä´N¦³¨Çµ{¦¡®v§i¶D§Ú¡GCOM¤£¬ODLL¡AÁöµM¥¦³q±`¤]¬O¥HDLL¨Ó§@¬°°ÆÀɦWªº¡A¥i¥L§¹¥þ»PDLL§¹¥þ¤£¦P¡C¨º»ò¡A³oºØ»¡ªk¬O§_¥¿½T©O¡H§Ų́ӬݬݡAn¹ê²{¤@Ó¶iµ{¤ºªºCOM¡A¨ì©³»Ýn¸g¹Lþ¨Ç¨BÆJ¡A¨º»ò¡A§ÚÌ´N¯à«Ü²M·¡ªºª¾¹Dµª®×¤F¡C
§¹¦¨¤@Ó¶iµ{¤ºªºCOM¡A³q±`»Ýn¥H¤U´X¨B¡G
1. «Ø¥ß¤@ÓDLL¶µ¥Ø¡A¨Ã¾É¥X¥H¤U¥|Ó¨ç¼Æ¡G
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
2. ©w¸q¦Û©w¸qªº¤¶±¡A¦P®É¥²¶·¹ê²{Iunknown¤¶±¡C
3. «Ø¥ßGUID¡A¥H¼ÐÃѳoÓ¤¸¥ó¥H¤Î¦Û©w¸qªº¤¶±¡C
4. ¦bµù¥Uªí¤¤µù¥U¥H¼Ð°O³oÓDLL¡C
¤j®a³£¬Ý¨ì¤F¡A¦b²Ä¤@Ó¨BÆJùØ¡A»Ýn«Ø¥ß¤@ÓDLL±M®×¡A¨º»ò¡A¬O¤£¬O·N¨ýµÛ¡ACOM´N¬O¤@ÓDLL©O¡H¦b³oùØ¡A§Ú¥i¥H©ú½T¦a§i¶D¤j®a¡A±q§Þ³N¤WÁ¿¡A¤@Ó¶iµ{¤ºªºCOM§¹¥þ¥i¥H³Q»{¬°´N¬O¤@Ó´¶³qªºDLL-°ÊºA³s±µ®w¡I¦pªG§A©ß±ó±`¥ÎªºCOM API¡A¤ñ¦pDELPHI¤¤±`¥Îªº¡G
CreateCOMObject()©ÎªÌ
CreateOLEObject()
¨º»ò±z§¹¥þ¥i¥Hª½±µ±Ä¥Î¸ü¤J´¶³qDLLªº¤è¦¡¨Ó½Õ¥Î³oÓCOM¤¸¥ó¡A¤ñ¦p»¡¡A±z¥i¥Hª½±µ¥ÎLoadLibrary()¨ç¼Æ¨Ó¸ü¤J³oÓDLL¡AµM«á¨Ï¥ÎGetProcAddress¨Ó½Õ¥Î±q³oÓDLLùØ¿é¥Xªº¤¶±¡A±q¦Ó§¹¦¨¦U¶µ¾Þ§@¡C³o¬O§¹¥þ¥i¦æªº¡CµM¦Ó¡A§Ú¤£±o¤£§i¶D¤j®a¡A§â¤@ÓCOM¶È¶È¬Ý¦¨¤@ÓDLL¡A¨º¬O«D±`½§²Lªº¬Ýªk - DLL¶È¶È¬O¤@ºØªí²{§Î¦¡¦Ó¤w¡C§ó«nªº¬O¡ACOM¹ê²{¤F¤@ºØ³W«h¡C¦]¦¹§ÚÌ¥i¥H»¡¡G
l COM¬O¤@ºØ¥]§t¤F³\¦h³B²zÅÞ¿è¡B²Å¦X¤F¬YºØ¤¶±³W½d¡]¦pIunknown³W½d¡^ªºDLL¤¸¥ó¡C
¡]ª`¡G¦pªG¨S¦³¯S§O»¡©ú¡A§Ú¦b¥»¤åùةҫüªºCOM¡A³£¬O«ü¶iµ{¤ºªºDLL§Î¦¡ªºCOM¡^
l COM¹ê²{¤FIunknown¤¶±¡C¦]¦¹¡A¥ô¦ó¥un²Å¦XIunknown³W½d¡A¹ê²{¤FIunknown¤¶±ªºDLL¤¸¥ó¡A§Ú̳£¥i¥H§â¥L¬Ý¦¨¬O¤@ÓCOM¡C
¨º»ò¡A¤°»ò¬OIunknown¤¶±©O¡H¦p¦ó¹ê²{¤@ÓIunknown¤¶±©O¡H§Ú̬ݬݡA¦bDELPHI¤¤¬O¦p¦ó©w¸q¤@ÓIunknown¤¶±ªº¡G
IInterface = interface
['{00000000-0000-0000-C000-000000000046}']
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
IUnknown = IInterface;
²³æ¤@ÂI¬Ý¡A§Ú̪½±µ³o¼Ë²z¸Ñ´N¦æ¤F¡G
IUnknown = interface
['{00000000-0000-0000-C000-000000000046}']
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
¦bDELPHIùØ¡Ainterface¬O½s;¹©Ò»{ÃѪº¤@ºØÃþ«¬¡C¦pªG¬O¦bVC++¤¤¡AIunknown±N³Q©w¸q¬°¤@ºØµ²ºc¡]struct¡^¡C¦pªGn¹ê²{¤@ÓIunknown¤¶±¡A§ÚÌ¥²¶·¥Î¤@ÓÃþ¨Ó¹ê²{¥¦¡A¤ñ¦p¦bDELPHI¤¤¡An¹ê²{Iunknown¤¶±¥i¥H¼g¦¨¬°¡G
TMyCOMObject = class (Tobject, Iunknown)
¡K¡K
end;
¦³¤ßªºÅªªÌ¥i¯à·|¥ß§Y°Ý¡G³oÓIunknown¤¶±¥ÑTobject¨Ó¹ê²{¡A¨º»ò¡A¥i¤£¥i¥H¬O¥Ñ¨ä¥LÃþ¨Ó¹ê²{©O¡H¤ñ¦p»¡¥ÎTcomponentÃþ¨Ó¹ê²{¡Hµª®×¬O¡G §¹¥þ¥i¥H¡I¡I
¨Ò¦p¡A§ÚÌn¹ê²{¤@Ó¦Û©w¸qªº¤¶±IMyCOM¡A¥i¥H¼g¦¨³o¼Ë¡G
IMyCOMTest = interface(Iunknown);
TMyCOMTest = class(Tcomponent, IMyCOMTest)
¡K¡K.
End;
³o¼Ë¬O§¹¥þ¥i¥Hªº¡I¦]¬°COMÃöª`ªº¥u¬O¦p¦ó¹ê²{¤@Ó¤¶±¡A¦Ü©óµ{¦¡®v¨Ï¥Î¤°»òÃþ¨Ó¹ê²{¡ACOM¬O¤£ºÞªº¡C
«á±§ÚÌn¹ê²{¤@ÓCOMªº¨Ò¤l¡A¦Ó¥B§Ú¥´ºâ´N¥Î³oÓIMyCOMTest¤¶±¨Ó°µ¡C©Ò¥H§Ú̧â³oÓ¤¶±Án©ú¦¨¬°¨Ò1¡A¥H«K«á±¨Ï¥Î¡C
COMªº²£¥Í
°²¦p§Ṳ́w¸g§¹¦¨¤F¤@ÓCOM¡A¨Ã¥B¤w¸g¦b¨t²Î¤¤µù¥U¤F¡C¨º»ò¡A¤@ӥΤáºÝ»Ýn¨Ó½Õ¥Î³oÓCOM¡A³o®É¡A¨t²Î¤¤µo¥Í¤Fþ¨Ç¨Æ©O¡H
¤@¯ë¨Ó»¡¡A¥HDELPHI¬°¨Ò¡A«È¤áµ{¦¡¨Ï¥ÎCreateCOMObject©ÎªÌCreateOLEObject½Õ¥ÎCOM¤¸¥ó®É¡A·|µo¥Í¥H¤U´XÓ¨BÆJ¡G
1. CreateCOMObject©ÎªÌCreateOLEObjectªº°Ê§@¡C
§Ú̬ݬݳo¨âÓ¨ç¼Æ³£·F¤F¨Ç¤°»ò¡G
function CreateComObject(const ClassID: TGUID): IUnknown;
begin
OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IUnknown, Result));
end;
CreateOLEObjectµy·L½ÆÂø¨Ç¡G
function CreateOleObject(const ClassName: string): IDispatch;
var
ClassID: TCLSID;
begin
ClassID := ProgIDToClassID(ClassName);
OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IDispatch, Result));
end;
¬Ý¨ì¤F¶Ü¡HCreateOLEObject¦h¤F¤@ÓProgIDToClassID¨ç¼Æ¡C³o·N¨ýµÛ¡A¦pªG§ÚÌn¥ÎCreateOLEObject¨Ó½Õ¥Î§Ú̪ºCOM¤¸¥ó¡A§Ú̱Nn¦h¤@¨Ç¨BÆJ¨Ó½s¼g§Ú̪ºCOM¡C³oÓ§Ú±N·|¦b«á±»¡©ú¡C²{¦b¡A§ÚÌnÃöª`ªº¬OCoCreateInstance API¨ç¼Æ¡C
2. CoCreateInstance API¨ç¼Æ±N½Õ¥ÎCoGetClassObject API¡A³oӽեιLµ{§Ú̬O¬Ý¤£¨ì¬ÛÃöªº¥N½Xªº¡A¦]¬°·L³n¤w¸g§â¥L«Ê¸Ë¦n¤F¡C¦ÓCoGetClassObject¨ç¼Æªº§@¥Î¬O¤°»ò©O¡H¥¦±N½Õ¥ÎLoadLibrary¨Ó´M§ä§ÚÌ«ü©wªºCOM¤¸¥ó¡]DLL¡^¡AµM«á¨Ï¥ÎGetProcAddress ¨Ó´M§ä¤¸¥óªº¤J¤f¨ç¼Æ - ÁÙ°O±o§Ṳ́W±»¡¹Lªº¨º¥|Ó³Q¾É¥Xªº¨ç¼Æ¶Ü¡H¹ï¡A¨ä¤¤ªºDllGetClassObject ¨ç¼Æ´N¦b³oùرN³Q½Õ¥Î¡C¸Ó¨ç¼Æªºì§Î¦bDELPHI¤¤¬O¡G
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;
¨ä¤¤²Ä¤TӰѼơGObj ¡A±N¦V§Ú̪ð¦^COM¤¤ªº©w¸qªº¤¶±¡C¦ý¬O¡Anª`·N¡A³oÓ¤¶±¨Ã¤£¬O§Ú̦۩w¸qªº¤¶±¡A¦Ó¬O¦V§Ú̪ð¦^¤F¤@Ó³Q¦¨¬°¬O¡§Ãþ¤u¼t¡¨¤¶±ªºIclassFactoryªº¤¶±¡C·í§ÚÌÀò±oÃþ¤u¼t¤¶±«á¡A´N¥i¥HÀò±o§Ú̩һÝnªº¡B¨ºÓ§Ú̦۩w¸qªº¤¶±¤F¡C¬Ý¬ÝIclassFactory ªº¤¶±Án©ú¡G
IClassFactory = interface(IUnknown)
['{00000001-0000-0000-C000-000000000046}']
function CreateInstance(const unkOuter: IUnknown; const iid: TIID;
out obj): HResult; stdcall;
function LockServer(fLock: BOOL): HResult; stdcall;
end;
¬Ý¨ì¨ºÓCreateInstance ªº¤èªk¤F¶Ü¡H¹ï¤F¡A¥¦ªº²Ä¤TÓ°Ñ¼Æ obj ±N¦V§Ú̪ð¦^¨ºÓ§ÚÌ©w¸qªº¤¶±¡A¤ñ¦p¬O§Ú̪ºIMyCOMTest¤¶±¡]¨Ò1¡^¡C³o¼Ë¡A§ÚÌ´N¥i¥H½Õ¥Î§Ú̦۩w¸qªº¤¶±¤èªk¤F¡C
¥H¤Wªº²³¦h¨BÆJ¬Ý°_¨Ó¦³ÂIÅý¤H°g´b¡C¨º»ò§ÚÌ´N¥Î¤@Ó²³æªº¬yµ{¨Ó´yø§ÚÌè¤~©Òµo¥Íªº¨BÆJ¡C¤£n³Q¨º¨Ç¨BÆJÀ~Ë¡A¨ä¹ê¥L̬O«D±`²³æªº¡C
l CreateCOMObject --à CoCreateInstance¡C CoCreateInstance ¦bµù¥Uªí¤¤¬d§äCOMªºµù¥U¸ê°T¡C
l CoCreateInstance -à CoGetClassObject ¡Cµù¥U¸ê°T³Q¥æµ¹CoGetClassObject¡C³o®ÉÔCoGetClassObject±Nª¾¹DCOM¤¸¥ó¦bºÏ¤ù¤Wªº¦ì¸m¡C
l CoGetClassObject -à LoadLibrary ¡CLoadLibrary ±N´M§äCOM DLLªº¤J¤f¡AµM«áGetProcAddress½Õ¥Î¨ä¿é¥X¨ç¼ÆDllGetClassObject
l DllGetClassObject ªº¿é¥X°Ñ¼Æ±N¦V§Ú̪ð¦^¡§Ãþ¤u¼t¡¨¤¶±IClassFactory¡C
l IclassFactory --à CreateInstance ¡CCreateInstance¤èªk«Ø¥ß¨ä§Ú̹ê²{¤¶±ªºÃþ¡C¸ÓÃþ±N½Õ¥Î¦Û¨ªºQueryInterface ¤èªk¡A¬d¬Ý¥Î¤á«ü©wªº¤¶±¬O§_³Q¦Û¤v¹ê²{¡A¦pªG¹ê²{¤F¡A«h¦Vªð¦^¦Û©w¸qªº¤¶±¡C
l ½Õ¥Îµ²§ô«á¡ACOM«È¤á±N½Õ¥ÎCOMªºDLL¿é¥X¨ç¼ÆDllCanUnloadNow ¡C¦pªG¸Ó¨ç¼Æªð¦^S_OK¡A«hÄÀ©ñ¸Ó¤¸¥ó¡C
¹ê»ÚªºCOM¨Ò¤l
¤U±§Ų́Ӱµ¤@Ó¹ê»Úªº¨Ò¤l¡C¥]¬A¦p¦ó«Ø¥ß¤@ÓCOM Server©M¤@ÓCOM Client¡C
¹ï©óCOM Server¡A§Ú̱N¹ê²{¥H¤U¥\¯à¡G
l ³æ½uµ{¡A³æ«È¤á¤ä´©¡C
l ¹ê²{¦Û©w¸qªº¤¶±
l ¯à°÷¨Ï¥ÎRegsvr32 ¦b¨t²Î¤¤µù¥U©M¤Ïµù¥U¡C
l ¯à°÷³QDELPHI©ÎªÌVC++µ{¦¡½Õ¥Î¡C
§ÚÌ¥uÃöª`¹ê²{³Ì°ò¥»ªº¥\¯à¡C·í¤j®a²M·¡¾ãÓ¬yµ{«á¡A¦ÛµM´N¯à¼g¥X§ó°ª¯Åªº¥\¯à¡A¤ñ¦p¦h½uµ{¤ä´©µ¥¡C
¤U±¡AÅý§Ú̶}©lCOM¹ê²{¤§®È¡C
COM Serverµ{¦¡
l ¦bDELPHI¤¤¡A·s«Ø¤@ÓDLL¤uµ{¡Cª`·N¬ODLL¡A¦Ó¤£¬O Activex Library¡C¨Ã§â¤uµ{¦W«O¦s¬°MyCOM¡CµM«á¨Ì¦¸«Ø¥ß¨âӳ椸ÀÉ¡G
MyCOMServer ³æ¤¸¡G ¦¹³æ¤¸´yz¤FCOMªºÅÞ¿è¹ê²{
COMDef ³æ¤¸¡G ¦¹³æ¤¸´yz¤FCOMªº¿é¥X¨ç¼Æ©w¸q¡C
l ¦bMyCOM³æ¤¸ùØ¡A§ÚÌ©w¸qDLLªº¿é¥X¨ç¼Æ¡A¾ãÓ¥N½X¡G
library MyCOM;
uses
SysUtils,
Classes,
COMDef,
MyCOMServer in 'MyCOMServer.pas';
//¦b³oùؾɥX¥|Ó¨ç¼Æ¡C
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
{$R *.res}
begin
end.
¥ý°µ¦n©w¸q¡A¤£n¦Ò¼{¥L̬O¦p¦ó¹ê²{ªº¡C³oÓ¦b«á±§Ú·|°µ¸Ô²Ó¸Ñ»¡¡C¦b³oùاڥý»¡©ú³o¥|Ó¨ç¼Æªº§@¥Î¡G
DllGetClassObject ¡G ªð¦^Ãþ¤u¼t¤¶±¡C
DllCanUnloadNow ¡G §i¶D¥Î¤áºÝ¸ÓCOM¬O§_¥i¥H³Q¥¿±`¨ø¸ü¡C
DllRegisterServer ¡G ¦V¨t²Îµù¥UCOM¤¸¥ó¸ê°T¡CRegsvr32.exe ´N¬O½Õ¥Î³oÓ¨ç¼Æ¨Ó¶i¦æµù¥Uªº¡C
DllUnregisterServer ¡G±q¨t²Î¤¤¤Ïµù¥U¤@ÓCOM¡CRegsvr32.exe ´N¬O½Õ¥Î³oÓ¨ç¼Æ¨Ó¶i¦æ¤Ïµù¥Uªº¡C
l ²{¦b¬°§Ú̪ºCOM©w¸qGUID¡Cª`·N¡A¦b¤@ÓCOM¤¸¥óùØ¡A¦³¤TºØGUID¡G
CLASS_xx Ãþ«¬ªºGUID¡A¬O¥Î¨Ó¼ÐÃÑCOM¤¸¥óªº¡C
IID_xxÃþ«¬ªºGUID¡A¬O¥Î¨Ó¼ÐÃѤ@Ó¤¶±ªº¡C¥i¥H¦³¦hÓ¡C
LIBID_xxÃþ«¬ªºGUID¡A¬O¥Î¨Ó¼ÐÃѤ@ÓTypeLibªº¡CÃö©ó¦p¦ó¹ê²{¤@ÓTypeLib¡A§Ú·|¦bCOM¹ê²{¹Lµ{¡]2¡^¤¤·|Á¿¨ì¡C¦b³oùØ¥ý²¤¹L¡C
²{¦b¡A§ÚÌ©w¸q§Ú̪ºCOM²Õ¥óªºGUID¡A¦bCOMDef³æ¤¸ùØ¥[¤Jªº¥N½X¬°¡G
const
Class_MyCOM: TGUID = '{CE38847E-A386-4753-89F1-34BE80042107}';
LIBID_MyCOM: TGUID = '{C2387E2A-0F08-442E-8947-D1AB36A9BDD0}';
l ¶}©l©w¸q§Ú̪º¤¶±¡C§Ú̱ĥΨҤ@©Ò©w¸qªº¤¶±¡A¦bMyCOMServer³æ¤¸ùØ¥[¤J¥N½X¡G
IMyCOMTest = interface(IUnknown)
['{D1C4A022-7F6F-42F0-A9B0-4A91703EB124}']
function msg: integer;stdcall;
end;
ª`·N¡A¦b³oùØ¡A§Ú̬°IMyCOMTest ©w¸q¤F¤@ÓIIDÃþ«¬ªºGUID¡A¥¦°ß¤@ªí¥Ü§Ú̪º¤¶±¡C¦P®É§ÚÌ©w¸q¤F¤@Ó¤èªk msg ¡A¥¦¦V§Ú̪ð¦^¤@Ó¾ã¼ÆÈ¡C
©w¸q¤F¤¶±¡A·íµMn¹ê²{¥¦¡G
TMyCOMServer = class(TObject, IMyCOMTest)
protected
FLock: integer;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
Constructor Create;
function msg: integer;stdcall;
end;
²{¦b¡A§Ṳ́@ÓÓªº¨Ó»¡©ú¨Ã¹ê²{TMyCOMServer ªº´XÓ¤èªk¡C
_AddRef ¤èªk¡G
¸Ó¤èªk¥Î©ó¼W¥[¤@ÓCOMªºp¼Æ¾¹¡C§Ú̪¾¹DCOM Server¬O»Ýn¤ä´©¦h«È¤á½Õ¥Îªº¡A¦bCOM¤¤¨C¹ê²{¤@¦¸½Õ¥Î¡A´N¥²¶·¶i¦æp¼Æ¡C¦pªGCOMªºp¼Æ>0 ¡A«hCOMÄ~Äò¥Í¦s¡C§_«h¡A¸ÓCOM¤¶±¹ê¨Ò´N¥²¶·³Qµn¥X¡C
_Release ¤èªk¡G
¸Ó¤èªk©M_AddRef¤èªk¬Û¤Ï¡A¥Î©ó´î¤Ö¤@Óp¼Æ¡A·íp¼Æ¬°0¡A«hµn¥X¸Ó¤¶±¡C
QueryInterface ¤èªk¡G
¸Ó¤èªk¥Î©ó¬d¸ß¤@Ó¤¶±¬O§_¦s¦b¡A¦pªG¦s¦b«h¦b¿é¥X°Ñ¼Æùتð¦^¸Ó¤¶±«ü¼Ð¡C
¬°¹ê²{³o´XÓ¤èªk¡A©Ò²K¥[ªº¥N½X¦p¤U¡G
function TMyCOMServer._AddRef: Integer;
begin
Inc(FLock);
end;
function TMyCOMServer._Release: Integer;
begin
Dec(FLock);
if FLock = 0 then
Free;
end;
function TMyCOMServer.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
//¦bÃþ¤u¼t¤¤¹ê²{ªº¤@ÓMC¤¶±¡A¦b³oùتð¦^¡C¥Ñ©ó§ÚÌ¥u¦³¤@Ó¤¶±¡A©Ò¥H¨ºÓIID°Ñ¼Æ¨S¦³¥Î¡C·íµM¡A¦pªG§Ú̹ê²{¤F¦hÓ¤¶±¡A´N»ÝnºûÅ@¤@Ó°}¦C¡A¥ÎÓCASE»y¥y¡A®Ú¾Ú¤£¦PªºIID¡A¨Óªð¦^¤£¦Pªº¤¶±¡C
Pointer(Obj) := Pointer(MC);
Result := S_OK;
end;
¨ä¤¤¡AMC¬O¤@ÓIMyCOMTest ¤¶±¡A¬OÓÁ`ÅéÅܼơG
var
MC: IMyCOMTest;
CF: IClassFactory;
§O§Ñ¤FÁÙ¦³§Ú̪ººc³y¾¹¡G
constructor TMyCOMServer.Create;
begin
Inc(FLock);
end;
¦b¤@¶}©l´N¼W¥[¤@Ó¤Þ¥Îp¼Æ¡A¨Ï±oCOMp¼Æ¤j©ó1¡A³o¼ËCOM´N¤£·|¦Û°Ê¾P·´¡C
µM«á¥h¹ê²{§Ú̪º¤¶±¤èªk¡G
function TMyCOMServer.msg: integer;
begin
result := 1978;
end;
¸Ó¤èªkª½±µ¦V§Ú̪ð¦^¤@Ó¾ã¼ÆÈ¡C
l Ãþ¤u¼tªº¹ê²{
¥¿¦p§Ú«e±©Ò»¡ªº¡A¤@ÓÃþ¤u¼t¥²¶·¥h«Ø¥ß§Ú̦۩w¸qªº¤¶±¡C¦b¤W±¡A§ÚÌ©w¸q¤F¦Û©w¸qªº¤¶±¡A¨Ã¥ÑÃþTMyCOMServer ¥h¹ê²{¡C¨º»ò¡A²{¦b§ÚÌÁÙn°µªº¬O¡A¹ê²{Ãþ¤u¼t¡AµM«á¥ÑÃþ¤u¼t«Ø¥ß¤@ÓTMyCOMServer ªº¤¶±¹ê¨Ò¡CÃþ¤u¼t¤¶±©w¸q¦p¤U¡G
IClassFactory = interface(IUnknown)
['{00000001-0000-0000-C000-000000000046}']
function CreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
out Obj): HResult; stdcall;
function LockServer(fLock: Boolean): HResult; stdcall;
end;
ª`·N¡AIclassFactory¬O¨t²Î¹w¥ý©w¸q¤Fªº¡A¦bACTIVEX³æ¤¸¦³¡A©Ò¥H¤£»Ýn¦Û¤v¦A¥h©w¸q¤@¦¸¡C§ÚÌ¥un¥h¹ê²{¥¦´N¬O¡G
TClassFactory = class(TObject, IClassFactory)
protected
FLock: integer;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
Constructor Create;
function CreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
out Obj): HResult; stdcall;
function LockServer(fLock: Boolean): HResult; stdcall;
end;
§ÚÌ¥uÃöª`CreateInstance ¤èªk¡CLockServer ¥Î©ó¦b¦h«È¤á½Õ¥ÎCOM®É¡AÂê©wCOM¡A¥H§K¤@ӫȤá°h¥X®É¾P·´¤FCOM¡A¨º»ò¨ä¥L«È¤áªº½Õ¥Î±Nµo¥Í¿ù»~¡C¦ý¬O§Ú̦b³oùØ¥u¹ê²{³æ«È¤á¡A©Ò¥H¤£¦Ò¼{³oÓ¨ç¼Æ¡A§â¥L¸mªÅ´N¬O¡C
function TClassFactory.CreateInstance(const UnkOuter: IInterface;
const IID: TGUID; out Obj): HResult;
begin
//§Ú̪º¦Û©w¸q¤¶±¡A´N¬O¦b³oùسQ³Ð«Øªº¡C
MC := TMyCOMServer.Create;
Pointer(Obj) := Pointer(MC);
end;
function TClassFactory.LockServer(fLock: Boolean): HResult;
begin
end;
¦P¼Ëªº¡ATclassFactory¤]¥²¶·¹ê²{¤Þ¥Îp¼Æ¡A¦]¬°¥¦¤]¹ê²{¤FIunknown¤¶±¡C
function TClassFactory._AddRef: Integer;
begin
Inc(FLock);
end;
function TClassFactory._Release: Integer;
begin
Dec(FLock);
if FLock = 0 then
Free;
end;
function TClassFactory.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
end;
¨ä¤¤¡AQueryInterface §Ú§â¥¦¸mªÅ¡A¦]¬°¦b³oÓ¨Ò¤l¤¤¡A¤£»Ýn¦V¥¦¬d¸ß¤°»ò¤¶±¡C¦pªG¥H«áŪªÌ»Ýn¦V¥¦¬d¸ß¤¶±®É¡A¦Û¤v¹ê²{¬ÛÃö¥N½X¡C
¦P¼Ë¡A¦b¥¦ªººc³y¾¹¤¤¡A¤]¹w¥ý¹ïp¼Æ¥[1
constructor TClassFactory.Create;
begin
Inc(FLock);
end;
¨ì¥Ø«e¬°¤î¡A§Ṳ́w¸g°ò¥»¹ê²{¤F¤@ÓCOM»Ýnªº¤j³¡¤À¥\¯à¡C²{¦b¡A§ÚÌ»Ýn§â¥¦µù¥U¨ì¨t²Î¤¤¡A¥H«K³Q¨ä¥Lµ{¦¡½Õ¥Î¡C
l COMªºµù¥U©M¤Ïµù¥U
§Ú̦^¹LÀY¨Ó¡A¬Ý¬Ý¦p¦ó¥h¹ê²{¨º¥|ÓDLLªº¿é¥X¨ç¼Æ¡C³o¥|Ó¨ç¼Æªºì§Î¦p¤U¡G
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;stdcall;
function DllCanUnloadNow: HResult;stdcall;
function DllRegisterServer: HResult;stdcall;
function DllUnregisterServer: HResult;stdcall;
§Ṳ́W±©Ò»¡ªºÃþ¤u¼tªº¹ê¨Ò¡A´N¬O¦bDllGetClassObject ¤¤³Ð«Øªº¡C¥N½X¦p¤U¡G
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;
begin
CF := TClassFactory.Create;
Pointer(obj) := Pointer(CF);
Result := S_OK;
end;
¦P¼Ëªº¡A§ÚÌ¥u¦³¤@ÓÃþ¤u¼t¡A©Ò¥H¥i¥H¤£²z·|«e±¨º¨âӰѼơC§_«h¡A´Nn®Ú¾Ú¤£¦PGUID¡A¨Ó³Ð«Ø¤£¦PªºÃþ¤u¼tª«¥ó¡C¦b³oùØ¡A§Ú̪½±µ§âÃþ¤u¼tª«¥óµ¹ªð¦^¤F¡C
¨ç¼ÆDllCanUnloadNow ¥Î¨Óµù¾P¤@ÓCOM¡C¦b¥¿±`¨Ï¥Î¤¤¡An®Ú¾Ú¤Þ¥Îp¼Æ¡A¨Ó§PÂ_¬O§_¤¹³\¥Î¤áµù¾P¡C¦b³oùاÚ̪½±µªð¦^S_OK¡AÅý¥Î¤áª½±µµù¾P¡C
function DllCanUnloadNow: HResult;
begin
Result := S_OK;
end;
¨ç¼ÆDllRegisterServer ¥Î¨Ó¦Vµù¥Uªíµù¥U¤@ÓCOM¤¸¥ó¸ê°T¡Cnµù¥U¤@ÓCOM¡A¥Î¤á¥²¶·ª¾¹DCOM¦bµù¥Uªí¤¤ªº¸ê°T¬O¦p¦ó²Õ´ªº¡Cµ²ºc¦p¤U¡G
HKEY_CLASSES_ROOT
---- CLSID
---- GUID
----- InprocServer32 ¼Ð©ú COM©Ò¦bºÏ¤ùªº¸ô®|¥H¤Î½uµ{¼Ò«¬
----- ProgID ¼Ð©úCOM©Ò¹ê²{ªº¤¶±
----- TypeLib ¼Ð©ú COM ªºÃþ«¬®wªºGUID
----- Version ¼Ð©ú COMªºª©¥»¸¹¡C
·íµo¥ÍCreateCOMObject()½Õ¥Î®É¡A¿é¤J°Ñ¼Æ¬°COMªºCLASSÃþ«¬ªºGUID¡A¨t²Î±N¦bµù¥Uªí¤¤·j¯Á¨ì¬ÛÃö¸ê°T¡AµM«á´N¥i¥H§ä¨ì¸ÓCOMªº¦ì¸m¡A´N¥i¥H¶}©l½Õ¥Î¤F¡C
ª`·N¡A¦pªG±z§Æ±æCOM¤¸¥ó¤ä´©¥Î¤áºÝªºCreateOLEObject()¨ç¼Æªº½Õ¥Î¡A±z¥²¶·ÁÙnµù¥U¤@Ó¸ê°T¡G
HKEY_CLASSES_ROOT
----- ¤¶±Án©ú
----- CLSID ¼Ð©ú COM ¤¶±©MCLASSÃþ«¬ªºGUIDªº¹ïÀ³Ãö«Y¡C
¨º»ò¡A·íµo¥Í CreateOLEObject ½Õ¥Î®É¡A¨t²Î±N·|®Ú¾Ú¿é¤J°Ñ¼Æ¡]¤@ÓCOM¤¶±Án©ú¡A¦pa.b¡^¡A¥h¬d§ä©M¤¶±¹ïÀ³ªºCLASS GUID¡AµM«á´N¥i¥HŪ¨ìCOMªº¬ÛÃö¸ê°T¤F¡C
¥þ³¡¥N½X¦p¤U¡G
function DllRegisterServer: HResult;
var
lp: pchar;
ns: Dword;
begin
Result := S_FALSE;
Reg := TRegistry.Create;
GetMem(lp, 255);
try
Reg.RootKey := HKEY_CLASSES_ROOT;
if Reg.OpenKey('\MyCOM.MyCOMTest',true) then
begin
Reg.CreateKey('CLSID');
if Reg.OpenKey('CLSID',true) then
Reg.WriteString('',GUIDToString(Class_MyCOM));
end;
if Reg.OpenKey('\CLSID\' + GUIDToString(Class_MyCOM), true) then
begin
if Reg.CreateKey('InprocServer32') = false or
Reg.CreateKey('ProgID') = false or
Reg.CreateKey('TypeLib') = false or
Reg.CreateKey('Version') = false then
Exit;
Reg.WriteString('','MyCOM');
if Reg.OpenKey('\CLSID\' + GUIDToString(Class_MyCOM) +
'\InprocServer32', false) then
begin
Windows.GetModuleFileName(HInstance,lp, 255);
Reg.WriteString('', lp);
Reg.WriteString('ThreadingModel', 'Single');
end;
if Reg.OpenKey('\CLSID\' + GUIDToString(Class_MyCOM) + '\ProgID', false) then
Reg.WriteString('','MyCOM.MyCOMTest');
if Reg.OpenKey('\CLSID\' + GUIDToString(Class_MyCOM) + '\Version', false) then
Reg.WriteString('','1.0');
if Reg.OpenKey('\CLSID\' + GUIDToString(Class_MyCOM) + '\TypeLib', false) then
Reg.WriteString('',GUIDToString(LIBID_MyCOM));
Reg.CloseKey;
Result := S_OK;
end;
finally
begin
FreeMem(lp);
Reg.Free;
end;
end;
end;
¨ç¼ÆDllUnregisterServer «h¦V¨t²Îµn¥X¤@ÓCOMªºµù¥U¸ê°T¡C¥¦¤ñ¸û²³æ¡Aª½±µ§âCOMªº¬ÛÃöµù¥UÁäµ¹§R°£´N¬O¡G
function DllUnRegisterServer: Hresult;
begin
Result := S_False;
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.DeleteKey('\CLSID\' + GUIDToString(Class_MyCOM));
Reg.CloseKey;
Finally
Reg.Free;
end;
end;
l ³Ì«á¤u§@¡C
²{¦b¡A§Ú̽s͵{§Ç¡AµM«á¥Í¦¨¤@ÓDLLÀÉ¡A¦b©R¥O¦æ¤U¡A¨Ï¥Î¡G
regsvr32 MyCOM.dll
¦V¨t²Îµù¥UCOM¡C
COM Clientµ{¦¡
¦bDELPHI¤¤½Õ¥Î
·s«Ø¤@Ó±M®×¡AµM«á¦b³æ¤¸¤¤¡A©w¸q¤¶±¸ê°T¡G
IMyCOMTest = interface(IUnknown)
['{D1C4A022-7F6F-42F0-A9B0-4A91703EB124}']
function msg: integer;stdcall;
end;
©w¸qÅܼơG
class_wjm: TGUID = '{CE38847E-A386-4753-89F1-34BE80042107}';
a: IMyCOMTest;
µM«á¦bµøµ¡ªºOnCreate ¨Æ¥óùØ¡A²K¥[¦p¤U¥N½X¡G
procedure TForm1.FormCreate(Sender: TObject);
begin
//ÀH«K¥ÎþÓ³£¥i¥H
a := createcomobject(class_wjm) as IMyCOMTest;
//©ÎªÌ¨Ï¥Î a := createoleobject('MyCOM.MyCOMTest') as IMyCOMTest;
end;
µM«á¡A©ñ¤@Ó«ö¶s¡A¨Ã¦b¨ä¨Æ¥óùزK¥[¥N½X¡G
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(inttostr(a.msg));
end;
¦bµ¡¤fªºOnCLose¨Æ¥ó¨½¥[¤W¡G
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
a := nil;
end;
ª`·N¤@©wnÄÀ©ñ¤¶±¡A§_«h¥i¯à¬OÓÃø¬Ýªº AV ¿ù»~®@¡C
¹B¦æ§Ú̪ºµ{¦¡¡AÂI¤U«ö¶s¡A§A±N¬Ý¨ì¿é¥X¸ê°T¡§1978¡¨¡C
¦pªG§A¬Ý¤£¨ì¥¿½Tªº¸ê°T¡A½Ð¥J²Ó¬d¬Ý§Aªº¥N½X¬O§_©M¤å¤¤¤@P¡C§A¤]¥i¥Hª½±µ¦V§Ú¯Án·½¥N½X¡C
¦bVC6¤¤½Õ¥Î
µy·L½ÆÂøÂI¡C¥ý§âGUID½Ķ¹L¨Ó¡G
//{CE38847E-A386-4753-89F1-34BE80042107};
static const CLSID CLSID_MyCOM = {0xCE38847E,0xA386,0x4753,
{0x89,0xF1,0x34,0xBE,0x80,0x04,0x21,0x07}};
//{D1C4A022-7F6F-42F0-A9B0-4A91703EB124}
static const IID IID_MyCOM = {0xD1C4A022,0x7F6F,0x42F0,
{0xA9,0xB0,0x4A,0x91,0x70,0x3E,0xB1,0x24}};
µM«á¦bÁn©ú¤@¦¸¤¶±ªº©w¸q¡G
struct IMyCOMTest : public IUnknown
{
virtual LONG __stdcall msg();
};
IMyCOMTest* pLink;
µM«á©ñÓ«ö¶s¤W¥h¡A¨Ã¦b¬ÛÃö¨Æ¥óùؼg¥N½X¡G
void CMyvcView::OnButton6()
{
pLink = NULL;
int a =0;
CoInitialize(NULL);
a = CoCreateInstance(CLSID_MyCOM, NULL,
CLSCTX_INPROC_SERVER,IID_MyCOM, (void**)&pLink);
if (a==S_OK){
LONG a= pLink->msg();
};
}
ª`·N¡A¤@©wn°O¦í½Õ¥Î CoInitialize(NULL); ³oÓ¨ç¼Æ¡A§_«hCOMµLªk¨Ï¥Îªº¡C
½s͹B¦æ¡A§AÀ³¸Ó¯à¬Ý¨ì a ¬Oµ¥©ó1978 ªº¡C
Á`µ²
¨ì¥Ø«e¬°¤î¡A§Ú̦¨¥\ªº½s¼g¤F¤@ӳ̲³æªºCOM¤¸¥ó¡A¨Ã¥B¦bDELPHI©MVC¤¤¦¨¥\½Õ¥Î¡C³o³£»¡©ú§Ú̪º¤u§@¬O¦¨¥\ªº¡C¦P®É§Ṳ́]¬Ý¨ì¡A¹ê²{¤@ÓCOM¡A¨Ã¤£Ãø¡C
Ãö©ó¶iµ{¥~ªºCOM¥H¤ÎDCOM¡A«eªÌ¬O°ò©óLPC ¥»¦aµ{§Ç©I¥s¡A«áªÌ¬O°ò©óRPC»·ºÝµ{§Ç©I¥s¡C°£¤F¨óij¤£¦P¥~¡A¨ä¥Lªº³£¤@¼Ë¡C¤j®a¦³¿³½ì¡A¥i¥H¥H«áÄ~Äò°Q½×¡C
Ãö©óCOMªº½uµ{¼Ò¦¡¡A§Ú´¿¸g¥H¬°¡A¬OCOMÂQ¾É¤¤¦Û°Ê·|²£¥Í¹ïÀ³ªº½uµ{¥N½X¡A¨Ó¹ê²{¦h½uµ{ªº¡C¦ý¬O§Ú«á¨Ó¤S»{¬°¡A®Ú¥»¨S¦³³o¦^¨Æ¡ACOM¥u¬O°µ¤FӼаO¡A§i¶D§@·~¨t²Î¥Lªº½uµ{¼Ò«¬¡A¦Ü©ó¦p¦ó²£¥Í½uµ{¡A«h¬O§@·~¨t²Î°µªº¡C¦³Ãö³o¤è±ªº°Q½×¡AÁÙ»Ýn¶i¤@¨B¬ã¨s¡C
¤@Ó¤p§À¤Ú
§Ú̪¾¹D¡A¦bDELPHIùØ¡A¦³¤@ÓImport Type Library ªº¥\¯à¡C¥i¥H§â¤@ÓCOM¤¸¥ó¾É¨ìDELPHI¤¤ª½±µ¨Ï¥Î¡C¦ý¬O¡A¦pªG§Ú̸չϧâ§ÚÌè¤~¼gªº¨ºÓ¤¸¥ó¡A¤]ADD¶i¥hªº®ÉÔ¡ADELPHI·|´£¥Ü¡G
¸ü¤JÃþ«¬®w/DLL®É¥X¿ù¡C
³o¬O«ç»ò¦^¨Æ©O¡H ì¨Ó¡A³o¬OMS/BORLANDªº¤@Ó¤pªá©Û¡C§Ú̬ݬÝVCLªº¥N½X´Nª¾¹D¤F¡A¦bDELPHIªºÂQ¾É¬°§A³Ð«Ø¤@ÓCOM®É¡A¥¦°½°½¦a¥[¤F¤@ÓIprovideClassInfo ªº¤¶±¶i¥h¡A¸Ó¤¶±¨Ï¥ÎItypeInfo ¤¶±¡A¥Dn¥Î©ó¦V¥~´£¨ÑCOMªºÃþ«¬¸ê°Tªº¡C¤j®a¥J²Ó¸ò¤UTtypedComObject ³oÓÃþ¡A´N·|µo²{³oÓ¶ø¯µ¤F¡C¦b«e¨Ò¤¤¡A§Ų́S¦³¹ê²{³oÓ¤¶±¡A¨º»ò·íµMµLªk³QDELPHI¸ü¤J¤F¡CÃö©ó¦p¦ó¹ê²{³oÓ¤¶±¡A¤w¸g¶W¥X¤F¥»¤åªº½d³ò¡A©Ò¥H¤£©ó°Q½×¡C
¦³¿³½ìªºªB¤Í¡A¥i¥HÄ~ÄòÃöª` ¡§COM¹ê²{¹Lµ{¡]2¡^¡¨¡A¥DnÁ¿z¦p¦ó¹ê²{Ãþ«¬®wªº¡C
2002/6/27
ª©Åv©Ò¦³
Âà¸ü®É½Ð¥]¬A§@ªÌ©m¦W
¹ê¥Î¬ÛÃö·j´M: ua now ½Ķ av °Q½× ª¯ ªá it cef ati