§@ªÌ¡G½²·ØÅï
¤é´Á¡GJan-2-2001¡@
ºKn¡G¤¶²Ð¥H DLL ¨Ó¤Á³ÎÀ³¥Îµ{¦¡ªº¹ê§@¤è¦¡¡A¨ä¤¤¥]§t¤¶±µ{¦¡³]pªº§Þ¥©¥H¤Î¹B¥Î Design Patterns ¨Ó¸Ñ¨M³]p¤Wªº°ÝÃD¡C
DLL¡]Dynamic Link Library¡A°ÊºAÁpµ²¨ç¦¡®w¡^´N¥Ø«e¨ÓÁ¿¤w¸g¤£¬O¤°»ò¤F¤£±oªº§Þ³N¡A§{¶¡®ÑÄyÀH¤â¾ß¤@¥»µøµ¡µ{¦¡³]p©Î Delphi ªº®ÑÄy³£¥i¥H§ä¨ì DLL ªº¬ÛÃö»¡©ú¡A¤Ö³o¤@½g¤]¤£ºâ¤Ö¡A¤§©Ò¥H¼g³o½g¤å³¹¡A¤@¤è±¬Oµ¹¦Û¤vªº¾Ç²ß¤ß±o§@Ó°O¿ý¡A¤@¤è±¤]´£¨Ñµ¹¦³»Ýnªº¤H°Ñ¦Ò¡F¦Ó¥»¤åªº¥DÃD¡Ð¡Ð³]p°ÊºA¸ü¤Jªº¼Ò²Õ¡Ð¡Ð»¡¬ï¤F¤]¥u¬O´£¨Ñ¤@Ó§â Form ¥]¦b DLL ¸Ì±ªº¹ê§@¤èªk¡A¾¨ºÞ¦p¦¹¡A§ÚÁÙ¬O§Æ±æ§A¯à¦b¨ä¤¤µo²{¤@¨Ç¤ñ¸û¤£¤@¼ËªºªF¦è¡C
¥Ñ©ó²{¦³Ãö©ó DLL ªº¤å¥ó¸ê®Æ¤w¸g«Ü¦h¡A¦b¦¹¤£¦h°µ«½Æ¡A¦]¦¹¦b¾\Ū¥»¤å®É·|»Ýn¤@¨Ç DLL ªº°ò¦ª¾ÃÑ©ÎªÌ DLL ªº¼¶¼g¸gÅç¡A³o¼Ë¾\Ū°_¨Ó·|¤ñ¸û»´ÃP¡C¥H¤U´N«ÂI¦¡¦a¦C¥X¤@¨Ç°ò¦Æ[©À¡G
DLL ¦b¨Ï¥Î¤W¤S¦³ÀRºA»P°ÊºA¸ü¤Jªº°Ï§O¡A©Ò¿×¡uÀRºA¸ü¤Jªº DLL¡v·N«ü¦b½sĶ®É´Á¤w¸g½T©wn³sµ²ªº DLL ¬Oþ¤@Ó¡A¦Ó¥B·|¦b¦æµ{ªì©l¤Æªº¶¥¬q´N³Q¸ü¤J¡ADelphi ªº VCL packages §YÄݦ¹Ãþ¡C°ÊºA¸ü¤Jªº DLL «h¬O°õ¦æ®É´Á»Ýn®É¤~¸ü¤J¡A¦bµ{¦¡¼¶¼g¤W¤ñÀRºA¸ü¤Jªº¤è¦¡³Â·Ð¨Ç¡A¦ý¸û¦³¼u©Ê¡A¥BÀ³¥Îµ{¦¡±Ò°Êªº³t«×¤]¸û§Ö¡C
¥»¤å©Òn°Q½×ªº´N¬O¥H°ÊºA¸ü¤Jªº DLL ¨Ó¹ê§@¥i©â´«ªºÀ³¥Îµ{¦¡¼Ò²Õ¡C
¤@¯ë¨Ó»¡¡A¨Ï¥Î DLL ¦³¤U¦CÀuÂI¡G
¦ý¤]·|¤@¨Ç§xÃø¥²¶·§JªA¡A·í§ÚÌn±NÀ³¥Îµ{¦¡¤Á³Î¦¨¼ÆÓ DLL ¼Ò²Õªº®ÉÔ¡A³q±`·|¸I¨ì¥H¤U´XÓ°ÝÃD¡G
°ò¥»¤W¡A¦pªG§A¼¶¼g¦¨ package ªº§Î¦¡´N¨S¦³¤Wz°ÝÃD¤F¡A¦ý§A¥i¯à·|¹J¨ì¨ä¥L³Â·Ð¡A¨Ò¦p¡G¦WºÙ½Ä¬ðªº°ÝÃD¡A³o¥]¬A¤F«¬ºA¡B³æ¤¸¦WºÙ¡B¨ç¦¡¦WºÙªº½Ä¬ð¡A¦b¦¹¤§«e§Ú¤]´¿¸ÕµÛ¥H package ªº¤è¦¡¨Ó¼¶¼g¥i©â´«ªº¼Ò²Õ¡A¦ý¦WºÙ½Ä¬ðªº°ÝÃD¥O§Úı±oÆZ§xÂZ¡C§Ú¤]´¿¦b¥t¤@¥÷¤å¥ó¤¤´£¤Î¦¹¨Æ¡A¥H¤U³o¬q¤å¦r¬O±q¸Ó¤åÂà¶K¤W¨Óªº¡]2¡^¡G
¡u¦b¼¶¼g´XÓ package ªº´ú¸Õµ{¦¡¤§«á¡A§ÚÁÙ¬O¨S¦³±N package À³¥Î¦b¹ê»Úªº±M®×¶}µo¤¤¡A¦Ó¤´µM¨Ï¥Î DLL¡A¨ä³Ì¥Dnªºì¦]¡A¥¿¬O package Àu©ó DLL ¤§³B¡Ð¡Ð¥i¥H¦@¨ÉÅܼơC³o¶µ¥\¯àªº¥ß·N«Ü¦n¡A¦ý¤]±a¨Ó¤F¥t¤@¨Ç¨î¡A¥Dn¬O¦WºÙ½Ä¬ðªº°ÝÃD¡A¨Ï±o¦@¥Îªº unit ¤@©wn©ñ¦b package ¸Ì±¡A§_«h·í¨âÓ package ¥]§t¤F¬Û¦Pªº unit¡A¨ä¤¤¤@Ó´NµLªk¸ü¤J¡A§ÚÌı±o³o·|³y¦¨³Â·Ð¡C¥t¥~¡A¥Ñ©ó¨ä¥Lªº¤p²Õ¦¨û¹ï©ó package ªº¨Ï¥Î¤£¼ô¡A®e©ö¥X trouble¡]¨Ò¦p¡Gproject n¥[¤J .dcp ¤§Ãþªº¡^¡A³o¤]¬O¦Ò¶q¤§¤@¡C¡v
¦b DLL ¤§¶¡¦@¨ÉÅܼƪº°ÝÃD¥i¥H³z¹L°O¾ÐÅé¬M®gÀÉ¡]memory-mapped file¡^¨Ó¸Ñ¨M¡A§A¥i¥H¦b¤å«á©Òªþªº°Ñ¦Ò¸ê®Æ¤¤§ä¨ì¬ÛÃö¸ê°T¡A³o¸Ì´N¤£ÂØz¡C¦Ó¦b DLL ¤¤¿é¥X VCL ª«¥ó¡]¨Ò¦p¡Gstring¡^®É±oª`·N¥H¤U´XÂI¡G
»P¨äÀH®Éª`·N³o¨Ç³W«h¡A¤]³\¿ï¾Ü¥i¥H§¹¥þÁ׶}³o¨Ç°ÝÃDªº¤èªk·|¤ñ¸û¦n¡A§Úªº·N«ä¬O¨Ï¥Î Windows ªº¼Ð·Ç«¬§O¨Ó¶Ç»¼¸ê®Æ¡A¨Ò¦pn¶Ç»¼¦r¦ê¡A´N¥Î PChar ¨Ó¥N´À string¡C¹ï¨ä¥L¸û¬°½ÆÂøªºµ²ºc¡A¥i¥H¨Ï¥Î¤¶±¨Ó¸Ñ¨M¡A³o·N¨ýµÛ¨â¥ó¨Æ±¡¡G
²Å¦X¤F¥H¤Wªº³W«h¡A¹ï©ó¦p¦ó±N Form ª«¥ó¥]¦b DLL ¸Ì±ªº°ÝÃD¤]´Nªï¤b¦Ó¸Ñ¡Aµy«á´N·|Á¿¨ì³o³¡¤À¦p¦ó¹ê§@¡C
¤¶±¡]interface¡^¦bª«¥ó¾É¦Vªº»â°ì¸Ì¬O¤@Ó«Ü«nªºÆ[©À¡A¥¦´yz¤FªA°È´£¨ÑªÌ©M¨Ï¥ÎªÌ¤§¶¡ªºÅv³d¡A©ÎªÌ»¡©w¸q¤F¨âÓª«¥ó¤§¶¡·¾³qªº¤è¦¡¡A³q±`³oÓ·¾³q¤è¦¡¤@¸g¨î©w´N¤£·|קï¡]²z·Qª¬ªp¤U¡^¡A¦]¦¹¤¶±¥ç¥iµø¬°ª«¥ó¤§¶¡ªº¦X¬ù¡C¥H OOP ªº¨¤«×¨Ó¬Ý¡A¤¶±´N¬O¤@²Õ¤½¶}ªº¤èªk¡]public methods¡^¡A¸òÃþ§O¤£¦P¤§³B¬O¥¦¨S¦³ private ¤Î protected µ¥¦s¨úµ¥¯Åªº°Ï§O¡A¤£¥i¥H¥]§t¸ê®Æ¦¨û¡A¤]¨S¦³¹ê§@ªºµ{¦¡½X¡A¥¦´N¥u¬O«Ü³æ¯Âªº....§c...¤¶±¡C¦b¤@Ó½ÆÂøªº¨t²Î¸Ì±¡A³oºØ³æ¯ÂÅã±o¯S§O¬Ã¶Q¡A±`±`±o¸g¹L¤@µf²`«ä¼ô¼{¤§«á¤~¯àµÑ¨ú¥X¸û¬°©â¶Hªº¦¨¤À¡A³o¤£¦ý¦³§U©ó§A¦b³]p®É¥H¤ñ¸û©â¶Hªº¼h¦¸¥h«ä¦Ò¡A¦P®É³]p¥X¨Óªº¤¶±¤]¤ñ¸û¯à°÷¦A®³¨Ó«½Æ¨Ï¥Î¡C¥H¥Î¤áºÝªº¨¤«×¨Ó¬Ý¡A¤¶±§â¨t²ÎI«áªº½ÆÂø«×ÁôÂäF°_¨Ó¡A¥Î¤áºÝ´N¥u»Ý±Mª`¦b¥¦»Ýnªº³¡¤À¡A¨Ï¥Î¤W·|¤ñ¸û®e©ö¡C |
©Ò¿×¥i©â´«ªº¼Ò²Õ¡A´N¬O«ü¦bµ{¦¡°õ¦æ®É°ÊºA¦a¸ü¤J»PÄÀ©ñªº¼Ò²Õ¡A¹ï©ó³W¼Ò¸ûÃe¤j¡A¥\¯à¸û½ÆÂøªºÀ³¥Îµ{¦¡¨Ó»¡¡A±NÀ³¥Îµ{¦¡¤Á³Î¦¨¼ÆÓ¿W¥ß¹B§@ªº¼Ò²Õ¦³¥H¤UÀuÂI¡G
¥H¤U·|¤@¨B¨B¹ê§@¥X¤@Ó¨ãÅé¦Ó·Lªº½d¨Ò¡A§A¥i¥H§â³oÓ½d¨Òµø¬°¤@Ó°ò¦ªº®Ø¬[¡]framework¡^¡Aµy¥[קï´N¥i¥H¹B¥Î©ó¹ê»Úªº±M®×¶}µo¤W±¡C
Åý§Ų́Ó²³æ¦a¤ÀªR¤@¤UÀ³¥Îµ{¦¡ªº»Ý¨D¡A°²³]쥻ªº¶}µo¤è¦¡¬O±N©Ò¦³ªºµ{¦¡³æ¤¸½sĶ³sµ²¦¨¤@Ó¥i°õ¦æÀÉ¡A²{¦bn±NÀ³¥Îµ{¦¡ªº¦UÓ¥\¯à¤Á³Î¬°¿W¥ßªº¼Ò²Õ¡A¨Ò¦p¡G
+--- «È¤á¸ê®ÆºûÅ@§@·~¡]Customer.DLL¡^ ¥Dµ{¦¡¡]Main.exe¡^---+--- ²£«~¸ê®ÆºûÅ@§@·~¡]Employee.DLL¡^ +--- q³æ¸ê®ÆºûÅ@§@·~¡]Orders.DLL¡^
¨ä¤¤¨CÓ DLL ³£¬O¦b¨Ï¥ÎªÌ°õ¦æ¸Ó¶µ¥\¯àªº®ÉÔ¤~°ÊºA¸ü¤J¡A¦Ó¥B¨CÓ DLL ¸Ì±¦Ü¤Ö¥]§t¤@Ó Form¡A¬°¤F¦³§O©ó¤@¯ëªº DLL¡A¥H¤U´N¥H plugin ºÙ¤§¡C§Ú̹w´Á¦U plugin DLL ©Ò¥]§tªº Form ·|¦³¤@¨Ç¦@¦PªºÄÝ©Ê©M¦æ¬°¡A¦]¦¹§â³o¨Ç¦@¦PÂI©ñ¨ì¤@Ó°ò¦µøµ¡Ãþ§O¸Ì±¡AÅý¨ä¥L Form Ä~©Ó¦Û³oÓ°ò¦Ãþ§O¡C¥¦ÌªºÃö«Y¬Ý°_¨Ó¹³³o¼Ë¡G
¨C¤@ÓºûÅ@§@·~³£»Ýn¶}±Ò¤@Óµøµ¡¡A¦]¦¹¥Dµ{¦¡ªº³d¥ô¤§¤@«K¬O«Ø¥ß¨ÃÅã¥Ü DLL ¸Ì±ªºµøµ¡¡C§Ú̧Ʊæ¨C¤@ÓºûÅ@§@·~ªºµøµ¡Ãö³¬«á¤~¯à°õ¦æ¥t¤@ÓºûÅ@§@·~¡A©Ò¥H¨Ï¥Î ShowModal ªº¤è¦¡Åã¥Üµøµ¡¡C°µ¤@¨Ç²³æªº¤ÀªR¤§«á¡A¥i¥H±o¨ì¥Dµ{¦¡¦b°õ¦æ¨C¶µ§@·~®É©Ò»Ýªº¦@¦P¨BÆJ¡G
¨ä¤¤¸ü¤J»P¬OÄÀ©ñ plugin DLL ªº¤u§@¥Ñ¥Dµ{¦¡t³d¡A¦Ó«e±¦³´£¹L DLL ¤¤ªºª«¥ó¥²¶·¥Ñ DLL ¦Û¤v¨Ó«Ø¥ß¡A¦]¦¹«Ø¥ß¡BÅã¥Ü¥H¤ÎÄÀ©ñ Form ª«¥óªº¤u§@³£¥Ñ plugin DLL ¨Ót³d´£¨Ñ¨ç¦¡¡A¥Dµ{¦¡¥un¦b¾A·í®É¾÷¥h©I¥s¥¦Ì´N¦æ¤F¡C
¦b¥Dµ{¦¡¤¤¥[¤J¤@Ó°õ¦æ plugin ªº¤èªk¡A¦¹¤èªk»Ýn¤@ӰѼƫü©w DLL ªºÀɦW¥H«K±N¨ä¸ü¤J°õ¦æ¡A¹³³o¼Ë¡G
procedure TMainForm.RunPlugin(const FileName: string); var ADllHandle: THandle; APlugin: IPlugin; AFormHandle: THandle; begin ADllHandle := SafeLoadLibrary(FileName); if ADllHandle <> 0 then begin APlugin := DllCreatePlugin(ADllHandle, Application.Handle); try AFormHandle := APlugin.CreateForm(Handle); APlugin.ShowModalForm; APlugin := nil; FreeLibrary(ADllHandle); except FreeLibrary(ADllHandle); raise; end; end else ShowMessage('µLªk¸ü¤J¨ç¦¡®w: ' + FileName); end;
±q¥H¤Wµ{¦¡½X¥i¥H¬Ý¥X¥Dµ{¦¡¸ü¤J DLL ¤§«á·|©I¥s DllCreatePlugin ¨Ó«Ø¥ß plugin ª«¥ó¨Ã¥B¨ú±o¨ä¤¶±°Ñ¦Ò¡A±µµÛ¥Dµ{¦¡´N§Q¥Î¸Ó¤¶±°Ñ¦Ò¨Ó¦s¨ú plugin ª«¥ó´£¨ÑªºªA°È¡A¥]¬A«Ø¥ßµøµ¡¡AÅã¥Üµøµ¡µ¥µ¥¡C«Ü©úÅã¦a¡AIPlugin ¤¶±¬O¥Dµ{¦¡©M plugin DLL ¤§¶¡·¾³qªº¾ô¼Ù¡A¦Ó¥B IPlugin ¤¶±¦Ü¤Ön´£¨Ñ¤U¦C¤èªk¡G
CreateForm - «Ø¥ß Form ª«¥ó
ShowModalForm - Åã¥Üµøµ¡
DestroyForm - ºR·´ Form ª«¥ó
²´¦yªºÅªªÌ¥i¯à·|µo²{¡A¤W±ªºµ{¦¡¤¤¨Ã¨S¦³©I¥s DestroyForm¡A¦Ó¥B¤]¨S¦³©I¥sÃþ¦ü DllDestroyPlugin ªº¨ç¦¡¨ÓºR·´ plugin ª«¥ó¡A³o¨Çª«¥ó¤°»ò®ÉÔ·|³QÄÀ©ñ±¼¡H
¥¦Ì¬O¦Û°Ê³QÄÀ©ñ±¼ªº¡C¥Ñ©ó Form ª«¥óªº«Ø¥ß¬O³z¹L plugin
ª«¥ó¨Ó§¹¦¨¡A©Ò¥H§Ú¥´ºâ§âºR·´ Form ª«¥óªº³d¥ô¥æµ¹ plugin ª«¥ó¡A¤]´N¬O·í plugin ª«¥óºR·´®É·|¦Û°Ê±N Form ª«¥ó¤@¨ÖÄÀ©ñ±¼¡F¦Ó¬°¤F²¤ÆºR·´ plugin ª«¥óªº°Ê§@¡A§ÚÅý plugin ª«¥ó¨ã¦³¦Û°Ê°Ñ¦Òp¼Æªº¯à¤O¡A³o»ò¤@¨Ó¥un¸Óª«¥ó¨S¦³¤H¨Ï¥Î¥¦¡]ª«¥óªº°Ñ¦Òp¼Æ¬° 0¡^´N·|¦Û°ÊÄÀ©ñ±¼¤F¡A°µªk«Ü²³æ¡A¥unÅý¹ê§@ IPlugin ªºÃþ§OÄ~©Ó¦Û TInterfaceObject ´N¦æ¤F¡A¨ä¥L²Ó¸`³£¥Ñ VCL À°§Ú̧¹¦¨¤F¡C
LoadLibrary »P FreeLibrary ¤]¦³¦Û¤vªº°Ñ¦Òp¼Æ¡A¨Ã¥B¥Î¥¦¨Ó¨M©w¬O§_¸ü¤J¤ÎÄÀ©ñ DLL¡C¤]´N¬O»¡«½Æ©I¥s LoadLibrary('A.DLL') ¨Ã¤£·|±N A.DLL ¸ü¤J¨â¦¸¡A²Ä¤G¦¸ªº©I¥s¥u·|»¼¼W°Ñ¦Òp¼Æ¦Ó¤w¡F¦P¼Ëªº¡AFreeLibrary ·|»¼´î DLL ªº°Ñ¦Òp¼Æ¡Aª½¨ìp¼Æ¬° 0 ¤~·|¯u¥¿±N DLL ÄÀ©ñ±¼¡C |
±µµÛ¬Ý DllCreatePlugin ¨ç¦¡¡G
type TCreatePluginFunc = function (hApp: THandle): IPlugin; stdcall; const SDllCreatePluginFuncName = 'CreatePlugin'; implementation resourcestring sErrorLoadingDLL = 'µLªk¸ü¤J¼Ò²Õ!'; sErrorDllProc = 'µLªk©I¥s DLL ¨ç¦¡: %s'; function DllCreatePlugin(hLib, hApp: THandle): IPlugin; var pProc: TFarProc; CreatePluginFunc: TCreatePluginFunc; begin pProc := GetProcAddress(hLib, PChar(SDllCreatePluginFuncName)); if pProc = nil then raise Exception.CreateFmt(sErrorDllProc, [SDllCreatePluginFuncName]); CreatePluginFunc := TCreatePluginFunc(pProc); Result := CreatePluginFunc(hApp); end;
DllCreatePlugin ·|¹Á¸Õ±q«ü©wªº DLL ¼Ò²Õ¤¤©I¥s¨ç¦¡ 'CreatePlugin' ¨Ó«Ø¥ß plugin ª«¥ó¡A¨Ã¥B¶Ç¦^ plugin ª«¥óªº¤¶±°Ñ¦Ò¡A°Ñ¼Æ hLib ¬O DLL ¥N½X¡A¦Ó hApp «hª½±µ¶Ç»¼µ¹ DLL ªºCreatePlugin ¨ç¦¡¡A³oӰѼƪº§@¥Îµy«á·|¸ÑÄÀ¡C
¦Ü¦¹¥Dµ{¦¡©Ò»Ýªºµ{¦¡½X¤jP¤W¤w¸g§¹¦¨¤F¡A±µ¤U¨Ó¬Ý¬Ý DLL ªº CreatePlugin ¨ç¦¡¡C
§Ú̪º plugin DLL ¥u¦³¿é¥X¤@Ө禡¨Ñ¥~¬É©I¥s¡A´N¬O«e±´£¨ìªº CreatePlugin¡A¨ä¨ç¦¡ì«¬¬°¡G
function CreatePlugin(hApp: THandle): IPlugin; export; stdcall;
CreatePlugin ¨ç¦¡·|«Ø¥ß TPlugin ª«¥ó¨Ã¥B¶Ç¦^ IPlugin ¤¶±ªº°Ñ¦Ò¡C¥Ñ©ó plugin ª«¥ó¶È»Ý³Q«Ø¥ß¤@¦¸¡A§ÚÌ¥i¥H¥Î¤@Ó¥þ°ìÅܼƹê§@¥X²³æªº Singleton¡]3¡^¡G
var g_PluginIntf: IPlugin = nil; implementation function CreatePlugin(hApp: THandle): IPlugin; begin Application.Handle := hApp; // Åý EXE »P DLL ¨Ï¥Î¦P¤@Ó application handle. if g_PluginIntf = nil then g_PluginIntf := TPlugin.Create; // TPlugin ªºª«¥ó°Ñ¦Òp¼Æ = 1 Result := g_PluginIntf; // TPlugin ªºª«¥ó°Ñ¦Òp¼Æ = 2 end;
CreatePlugin »Ýn¶Ç¤J¤@Ó°Ñ¼Æ hApp¡A¥Nªí©I¥sªÌµ{§Çªº Application ª«¥óªº Handle¡A³q±`¬O¶Ç¤J Application.Handle¡A¦nÅý¥Dµ{¦¡©M DLL ªº Application ª«¥ó¯à°÷¡u¦P¨B¡v¡C¤§©Ò¥Hn³o»ò°µ¬O¦]¬°·í§Aªº DLL ±M®×¥¼¨Ï¥Î "Build with runtime package" ¿ï¶µ®É¡A°õ¦æÀÉ©M¸ü¤Jªº DLL ·|¦U¦Û¦³¤@Ó Application ª«¥ó¡A¦ý¬O¥u¦³°õ¦æÀɪº Application ª«¥ó¦³³sµ²¤@Óµøµ¡¡ADLL «h¨S¦³¡A¦]¦¹ DLL ªº Application.Handle ÄÝ©ÊÁ`¬O¬° 0¡CY¤Ö¤F³oÓ¦P¨Bªº°Ê§@¡A¨º»ò·í DLL ªº Form ¶}±Ò®É¡A§A·|¦b®à±ªº¤u§@¦C¤W¬Ý¨ì¦h¤F¤@Óµøµ¡«ö¶s¡A¬Ý°_¨Ó´N¹³°õ¦æ¤F¥t¤@ÓÀ³¥Îµ{¦¡¤@¼Ë¡A§Ṳ́£§Æ±æ¬Ý¨ì³oºØ±¡§Î¡C
·íµM°Õ¡A¦pªG§Aªº¥Dµ{¦¡©M DLL ³£¨Ï¥Î "Build with runtime packages" ¨Ó«Ø¥ß¡]§AÀ³¸Ó³o»ò°µ¡^¡A´N¤£»Ýn³oÓ¦P¨B°Ê§@¤F¡]·Q·Q¬Ý¬°¤°»ò¡H¡^¡C
µ{¦¡½X¸Ì±¦³¨â¦æÃö©óª«¥ó°Ñ¦Òp¼Æªºµù¸Ñ¡A¬O·Qnªí¹F¤¶±µ{¦¡³]pªº¤@Ó°ò¥»Æ[©À¡G·í¤@Ó¤¶±°Ñ¦Ò¦b¨ç¦¡¤§¶¡¥H pass by value ªº¤è¦¡¶Ç»¼®É·|»¼¼Wª«¥óªº°Ñ¦Òp¼Æ¡]pass by reference «h¤£·|¡^¡C¦¹Æ[©À¦³§U©ó§A¥¿½T´x´¤ª«¥óªº¹Ø©R¡C
³Ì«á§O§Ñ¤FÁÙn§â³o¿é¥X¨ç¦¡¥[¨ì±M®×ì©l½Xªº exports ¤l¥y¸ÌÀY¡G
exports CreatePlugin;
IPlugin ¤¶±©w¸q¦p¤U¡G
IPlugin = interface ['{D3F4445A-C704-42BC-8283-822541668919}'] // «ö Ctrl+Shift+G ²£¥Í GUID function CreateForm(hMainForm: THandle): THandle; procedure DestroyForm; function ShowModalForm: Integer; end;
¨ä¹ê¥H¤W¨ç¦¡¤]¥i¥H¼g¦¨¤@¯ëªº DLL ¨ç¦¡¡A·í§@¬O DLL ªº¤¶±¡A¤§©Ò¥H¥t¥~©w¸q³oÓ¤¶±¡A¤@¤è±¬O§Æ±æ²¤Æ DLL ¥»¨ªº¤¶±¡A¥t¤@¤è±¤]¥i¥H¶°¤¤ºÞ²zµ{¦¡½X¡A¥H«á¦pªG»Ýn¼W¥[¤¶±¤èªkªº¸Ü¡A¥un¥[¦b IPlugin ¤¶±¸Ì±´N¦n¤F¡A¤£¥Î§â²{¦³ªº DLL ì©l½X¤@ÓÓ§ä¥X¨Óקï¡A³o¤]¦³§U©ó²¤Æ DLL ªº¼¶¼g¥H¤Î¤é«áªººûÅ@¤u§@¡C
¤¶±¤£¥]§t¹ê§@¡A¹ê§@¥²¶·¥ÑÃþ§O¨Ó´£¨Ñ¡C |
±µµÛ©w¸q¤@Ó TPlugin Ãþ§O¨Ó¹ê§@ IPlugin ¤¶±¡G
TPlugin = class(TInterfacedObject, IPlugin) private FForm: TForm; public destructor Destroy; override; function CreateForm(hMainForm: THandle): THandle; procedure DestroyForm; function ShowModalForm: Integer; end;
¦b IPlugin ¤¤¥[¤W GUID ¥H¤ÎÅý TPlugin Ä~©Ó¦Û TInterfacedObject ªº¥Øªº¡A¬O¬°¤FÅýª«¥ó¾Ö¦³ Interfaced RTTI ¥H¤Î¦Û°Ê°Ñ¦Òp¼Æªº¯à¤O¡A³o¼Ë§Ú̪º TPlugin ª«¥ó´N·|¦b¨S¦³¥ô¦ó¤H¨Ï¥Î¥¦®É¦Û°ÊÄÀ©ñ±¼¡C¨p¦³¦¨û FForm °O¿ý¤F¦¹ plugin ª«¥ó©Ò«Ø¥ßªºµøµ¡ªº°Ñ¦Ò¡A¥H«K±±¨î¨ä¹Ø©R¡A¨ä«¬ºA¤]¥i¥Hµø»Ýn§ï¦¨ TBaseForm¡A¨º»ò§Aªº TBaseForm ªº³]p±oºÉ¶q¤£n¸g±`קï¡A©ÎªÌ»¡³]p±o©â¶H¤@¨Ç¡AÅý³o¨Ç®Ö¤ßªºÃþ§O¦b¤ñ¸û©â¶Hªº¼h¦¸¤W±¹B§@¡C
¦UÓ¤èªkªº¦WºÙ¬Ò¥i±æ¤å¥Í¸q¡Aµ{¦¡½X¤]«Ü²³æ¡A¬Û«H§A¥i¥H²qÓ¤K¤E¤£Â÷¤Q¡A³o¸Ì´N¤£¤@¤@¦C¥X¡A¤ñ¸ûȱo¤@´£ªº¬O CreateForm ¨ç¦¡»P¸Ñºc¤¸ Destroy¡A¤Àz¦p¤U¡G
¦b CreateForm ¨ç¦¡¸Ì±¡A«Ø¥ß Form ª«¥óªº¨º¦æµ{¦¡¬O³o»ò¼gªº¡G
FForm := g_ConcreteClass.Create(Application);
¨ä¤¤ g_ConcreteClass ¬O¤@Ó¥þ°ìÅܼơA¨ä©w¸q¬°¡G
var g_ConcreteClass: TBaseFormClass := nil;
¦Ó TBaseFormClass ¬O¤@ÓÃþ§O°Ñ¦Ò«¬ºA¡]class-reference type¡^¡A¥¦¸ò TBaseForm ©w¸q¦b¦P¤@ӳ椸¸Ì±¡G
type TBaseFormClass = class of TBaseForm; TBaseForm = class(TForm) ..... end;
¤]´N¬O»¡§Ú̥Τ@ÓÃþ§O°Ñ¦Ò«¬ºAªºÅÜ¼Æ g_ConcreteClass ¨Ó°O¿ý±ý¹êÅé¤ÆªºÃþ§O«¬ºA¡A¦]¦¹¦b«Ø¥ß Form ª«¥ó¤§«eÁÙ¥²¶·¥ý³]©w g_ConcreteClass ¤~¦æ¡A¦p¦¹ TPlugin ¤~¯à¥H¥¿½Tªº Form Ãþ§O¨Ó¶i¦æ¹êÅé¤Æªº°Ê§@¡C
±z©Î³\·|·Q¬°¤°»òn³o»ò³Â·Ð¡Aª½±µ¼g¦¨¹³ TCustomerForm.Create ³o¼Ë¤£´N¦n¤F¶Ü¡H
²³æ¦a»¡¡A¬O°ò©óºûÅ@ªº¦Ò¶q¡C¥Ñ©ó¦b¾ãÓ TPlugin ªº¹ê§@¸Ì±¡A¤é«á°ß¤@¥i¥H¯à·|¸g±`Åܰʪº´N¬On³Q¹êÅé¤Æªº Form Ãþ§O¡A¨Ï¥ÎÃþ§O°Ñ¦Ò¨Ï§Ú̧K©ó¦b TPlugin ªº¹ê§@µ{¦¡½X¸Ì±§âÃþ§O«¬ºA¼g¦º¡A¥H«á¦pªGn¹êÅé¤Æ¨ä¥Lªº Form Ãþ§O¡A¥unקï g_ConcreteClass ³oÓÅܼƴN¦æ¤F¡A¤£¥Î¦A¶O¤@µf·j´M¤Î´À´«¤å¦rªº¥\¤Ò¡AÁÙ±o¾á¤ß¦³¨S¦³þ¸Ì¨S¦³§ï¨ì¡F´«¥y¸Ü»¡¡A§Ú̵¥©ó¨Ï¥ÎÃþ§O°Ñ¦Ò¨ÓÅý½sĶ¾¹À°§Ú̧¹¦¨³oÓ´À´«¤å¦rªº°Ê§@¡A¦Ó¥B«OÃÒ¤£·|¿òº|¥ô¦ó¦a¤è¡C
§Ú¥æ´À¨Ï¥Î¤F¡u«Ø¥ßª«¥ó¡v»P¡u¹êÅé¤Æ¡v¨âºØµü·J¡A¨ä¹ê¥¦Ì«üªº¬O¦P¤@¥ó¨Æ±¡¡G«Ø¥ß¬YÓÃþ§Oªº¹êÅé¡]instance¡^¡C |
¦¹§Þ¥©¹ï©ó¹Î¶¤¶}µo¤]¦³¦n³B¡A§A¥un¤½§G TPlugin ©M TBaseForm ¨âӳ椸¡AµM«á§i¶D²Õû·Ó¤U±¨âÓ¨BÆJ°µ´N¦æ¤F¡G
¦b³oÓ½d¨Ò¸Ì±¡A§ÚÌ¥u¦³¤@Ó TBaseForm ªº«á¥N¡A¥s°µ TForm1¡A¦]¦¹¦b TForm1 ªº³æ¤¸¸Ì±·|¦³³o¤@¬q¡G
uses DllExport; // TPlugin Ãþ§O¹ê§@©ñ¦b³oӳ椸¸Ì± ..... initialization g_ConcreteClass := TForm1;
¡@
¸Ñºc¨ç¦¡·|©I¥s DestroyForm ¨Ï Form ª«¥ó¤@¨ÖÄÀ©ñ±¼¡A¨Ã¥BÁÙì DLL ªº application handle¡G
destructor TPlugin.Destroy; begin DestroyForm; Application.Handle := g_DllAppHandle; inherited Destroy; end;
¨ä¤¤ g_DllAppHandle ¬O¤@Ó¥þ°ìÅܼơA¨ä«Å§i¦p¤U¡G
var g_DllAppHandle: THandle;
¦Ó§ÚÌ¥²¶·¦b DLL ªì©l¤Æªº®ÉÔ±N DLL ¥»¨ªº application handle «O¦s°_¨Ó¡G
initialization g_DllAppHandle := Application.Handle;
¨ä¹ê¦pªG DLL ±M®×¦³¥Î "Build with runtime package" ¿ï¶µªº¸Ü¡A³oÓ«O¦s¤ÎÁÙì application handle ªº°Ê§@´N¥i¥H§K¤F¡C¬Û¤Ï¦a¡AY¤£¥[¤W«O¦s¤ÎÁÙ쪺°Ê§@¡A¦Ó¥B DLL ±M®×¤£¨Ï¥Î "Build with runtime package" ¿ï¶µªº¸Ü¡A·í DLL ³QÄÀ©ñ®É´N·|µo¥Í¥Dµøµ¡¤]³Q¤@¨ÖÃö³¬ªº©Ç²§±¡§Î¡C
¨ì¦¹«nªº³¡¤ÀÀ³¸Ó³£¤w¸g´£¨ì¤F¡A±z¥i¯à·|µo²{§Ú¨Ã¨S¦³¹ï TBaseForm ¦h°µ»¡©ú¡Aì¦]¬O¦b³oÓ½d¨Òµ{¦¡¤¤ TBaseForm ¨Ã¨S¦³¤°»ò¯S§O¤§³B¡A¥u¬O¬°¤é«áÂX¥R®É¹w¯dªº¤@Ó°ò¦Ãþ§O¡A§A¤]³\·|·Qn±N¦UÓ¼Ò²Õ¦@¥Îªº¥\¯à©Mµøı¤Æ¤¶±¶°¤¤¦b¦¹Ãþ§O¥H²¤Æ¦U¼Ò²Õªº¼¶¼g¤u§@¡A¥H¤ÎÅýÀ³¥Îµ{¦¡¦³¤@Pªº¾Þ§@¤è¦¡©M¦æ¬°¡A³o³¡¤À¨CÓ¤Hªº»Ý¨D¤£¦P¡A´N½Ð±z¦Û¦æµo´§¤F¡C
¦pªG§Aı±o¥H¤Wªºµ{¦¡½X¹L©ó¤ù¬q¹s´²¡AµLªkÀò±o¾ãÅ骺·§©À¡A«Øij±zª½±µ¬Ý½d¨Òªºì©l½X¡A§â½d¨Òµ{¦¡°õ¦æ¤@¹M¥HÆ[¹îµ{¦¡¹B§@ªº¹Lµ{¡A¤£¤F¸Ñªº¦a¤è¦A¦^¨Ó¤å¥ó¸Ì´M§ä¸ÑÄÀ¡A³o¼Ë¤]³\·|¤ñ¸û®e©ö¨Ç¡C¬°¤F¤è«K¾\Ū¡A§Ú¤]§â½d¨Òµ{¦¡¤¤¤ñ¸û«nªº¨âӳ椸¤À§O¦C¦bªí¤@©Mªí¤G¸Ì±¤F¡C
¦Cªí¤@. DllUtils.pas |
unit DllUtils; interface uses Windows, Messages, SysUtils, Classes, Forms, Controls; type IPlugin = interface ['{D3F4445A-C704-42BC-8283-822541668919}'] function CreateForm(hMainForm: THandle): THandle; procedure DestroyForm; function ShowModalForm: Integer; end; TCreatePluginFunc = function (hApp: THandle): IPlugin; stdcall; function DllCreatePlugin(hLib, hApp: THandle): IPlugin; implementation resourcestring sErrorLoadingDLL = 'µLªk¸ü¤J¼Ò²Õ!'; sErrorDllProc = 'µLªk©I¥s DLL ¨ç¦¡: %s'; const SDllCreatePluginFuncName = 'CreatePlugin'; function DllCreatePlugin(hLib, hApp: THandle): IPlugin; var pProc: TFarProc; CreatePluginFunc: TCreatePluginFunc; begin Result := nil; if hLib = 0 then Exit; pProc := GetProcAddress(hLib, PChar(SDllCreatePluginFuncName)); if pProc = nil then raise Exception.CreateFmt(sErrorDllProc, [SDllCreatePluginFuncName]); CreatePluginFunc := TCreatePluginFunc(pProc); Result := CreatePluginFunc(hApp); end; end. |
¡@
¦Cªí¤G. DllExport.pas |
unit DllExport; interface uses Windows, Classes, Forms, DllUtils, BaseFrm; type // Inherited from TInterfacedObject to be reference-counted. TPlugin = class(TInterfacedObject, IPlugin) private FForm: TBaseForm; public destructor Destroy; override; function CreateForm(hMainForm: THandle): THandle; procedure DestroyForm; function ShowModalForm: Integer; end; function CreatePlugin(hApp: THandle): IPlugin; export; stdcall; exports CreatePlugin; var g_ConcreteClass: TBaseFormClass := nil; g_PluginIntf: IPlugin = nil; g_DllAppHandle: THandle; implementation uses Dialogs, SysUtils; function CreatePlugin(hApp: THandle): IPlugin; begin if hApp <> 0 then Application.Handle := hApp; // Sync Application handle. if g_PluginIntf = nil then g_PluginIntf := TPlugin.Create; Result := g_PluginIntf; end; { TPlugin } destructor TPlugin.Destroy; begin DestroyForm; Application.Handle := g_DllAppHandle; inherited Destroy; end; function TPlugin.CreateForm(hMainForm: THandle): THandle; begin if FForm = nil then begin Assert(g_ConcreteClass <> nil, '¥¼³]©w±ý¹êÅé¤Æªº Form Ãþ§O¦WºÙ!'); FForm := g_ConcreteClass.Create(Application); FForm.MainFormHandle := hMainForm; end; Result := FForm.Handle; end; procedure TPlugin.DestroyForm; begin if FForm <> nil then begin FForm.Release; FForm := nil; end; Application.ProcessMessages; end; function TPlugin.ShowModalForm: Integer; begin if FForm = nil then raise Exception.Create('DllExoprt: µøµ¡©|¥¼«Ø¥ß!'); Result := FForm.ShowModal; end; initialization g_DllAppHandle := Application.Handle; end. |
¡@
½d¨Òµ{¦¡¥i¥H«ö¦¹³B¤U¸ü¡GPluginDLL.zip
¤U¸üÀ£ÁYÀɨøѶ}«á¡A½Ð¥ý¾\Ū¨ä¤¤ªº readme.txt¡C
§A¥i¥H¸ÕµÛקï½d¨Òµ{¦¡¨Ã±j¤Æ¥¦¡A¨Ï¥¦¥i¥H·í§@¹ê»Ú¶}µo±M®×ªº°ò¦®Ø¬[¡A¥H¤U¦C¥X´X¶µ¥i¯àªº§ï¶i¤§³B¡G
§A¥i¯à·|§Æ±æ¤@Ó DLL ¸Ì±¥i¥H´£¨Ñ¦hºØ form ª«¥ó¨Ñ¥Dµ{¦¡¨Ï¥Î¡A³o¨Ç form ª«¥ó¤§¶¡¥i¯à¦³¬YºØµ{«×ªº¬Û¦ü©Î¬Û¨ÌÃö«Y¡C®Ú¾Ú¦¹»Ý¨D§ÚÌ¥i¥H¾ã²z¥X plugin ª«¥ó¨ã³Æ¥H¤U¨âÓ¯S©Ê¡G
- plugin ª«¥ó¥i¥H«Ø¥ß¦hºØ¤£¦PÃþ«¬ªº form ª«¥ó¡A¦Ó¥¦Ì³£¬OÄ~©Ó¦Û°ò¦ªºªí³æÃþ§O TBaseForm¡C
- ¤@Ó DLL ¸Ì±¥u»Ýn¤@Ó plugin ª«¥ó¡C
®Ú¾Ú [GHJV95] ®Ñ¤¤ªº©w¸q¡AAbstract Factory ªº¥Î·N¬O¡G
¡u´£¨Ñ¤@Ó¤¶±¨Ó«Ø¥ß¦P¤@±Ú¨t©Î¬Û¨Ìªºª«¥ó¡A¦Ó¤ð¶·«ü©ú¥¦Ìªº¨ã¶HÃþ§O¡]concrete class¡^¡v
¦Ó Factory ³q±`¤]³Q¹ê§@¦¨ Singleton¡A³o¨Ç¯S©Ê²M·¡¦a§i¶D§ÚÌ plugin ª«¥ó«D±`¾A¦X¹ê§@¦¨¤@Ó Factory¡C§A¥i¯à»Ýn¦b TPlugin Ãþ§O¸Ì±´£¨Ñ¤@Ó RegisterClass ¤èªk¡A³oÓ¤èªk¨ú¥N¤Fì¥ýªºÃþ§O°Ñ¦Ò«¬ºA¡A쥻¦b TBaseForm ¤lÃþ§Oªº³æ¤¸¸Ì³]©w g_ConcreteClass ªº±Ôz±N·|§ï¦¨¡G
PluginFactory.RegisterClass(TForm1);µù¥U¹LªºÃþ§O¸ê°T±N·|³Q°O¿ý¦b¤@Ó¦ê¦C¸Ì±¡C¥Dµ{¦¡«h¥i¥H¦b«Ø¥ß form ª«¥ó®É³z¹L¦r¦ê¨Ó«ü©wn«Ø¥ßªº form Ãþ§O¦WºÙ¡A¹³³o¼Ë¡G
APlugin.CreateForm('TCustomerForm');plugin ª«¥óªº CreateForm ¤èªk´N·|¨ì¦ê¦C¤¤·j´Mµù¥U¹LªºÃþ§O¡A¨ú±o¹ïÀ³ªºÃþ§O°Ñ¦Ò¨Ã«Ø¥ß¨ä¹êÅé¡]¬O¤£¬O¦³ÂI¹³ COM ©Ò°µªº¨Æ±¡¡H¡^¡C
¶â¡A§Ú·Q³o¼Ëªº´£¥ÜÀ³¸Ó°÷¤F¡A³Ì«nªºÁÙ¬On¦Û¤v¹ê»Ú¥h¼¶¼g¤Î°£¿ùµ{¦¡½X¥HÀò±o§ó²`¨èªºÅé·|¡A¯u¯à¦p¦¹¡A³oÓ Design Pattern ´N·|§¹¥þ¿Ä¤J§Aªºª¾ÃÑÅé¨t¸Ì±¡A¥H«á¤£¥[«ä¯Á«K¥i¥H¹B¥Î¦Û¦p¤F¡C
¦b³o¥÷¤å¥ó¸Ì±¥Dn¬O¤¶²Ð¥H Delphi ¨Ó³]p plugin ¼Ò²Õªº¹ê§@¹Lµ{¡A¨ä¤¤¹B¥Î¤F¤¶±µ{¦¡³]pªº§Þ¥©¡]¥]¬A¤¶±ªº°Ñ¦Òp¼Æ¥H¤Îª«¥ó¥Í©R¶g´Áªº±±¨î¡^¥H¤Î Design Patterns ¨Ó¸Ñ¨M³]p®É¾D¹Jªº°ÝÃD¡A³o¤]¬O¾Ç²ßªº«ÂI¤§¤@¡C
¦b¤@Ó¦h¤H¶}µoªº±M®×¸Ì¡A¦pªG±zªº³d¥ô¬O³]p¥Dµ{¦¡®Ø¬[¡A·í±zn¥H DLL ¨Ó¤Á³ÎÀ³¥Îµ{¦¡®É·|«ç»ò°µ©O¡H³o½g¤å³¹¸Ì±®i¥Ü¤F¤@ºØ¥i¯àªº³]p¤è¦¡¡A¦pªG±z¦³¤£¦Pªº·Qªk©ÎªÌ¹ï¥»¤å¦³¥ô¦ó«Øij¡A³£«ÜÅwªï±z¨Ó«H«ü±Ð¡C
³Ì«á¡AÁöµM¤£¬O¥»¤åªº¥DÃD¡A¦ý¤]»áȱoª`·Nªº¡A´N¬O°ÊºA¸ü¤Jªº DLL ¦bÄÀ©ñ®É·|¦³ 4K ªº°O¾ÐÅéº|¬}¡A¦Ó¥B Delphi 5 ©M 6 ³£¦³³oÓ°ÝÃD¡A§A¥i¥H¾\Ū¤U±¨â¥÷¤å¥ó¡A¨ä¤¤¦³¸Ô²Óªº»¡©ú¨Ã´£¨Ñ¸Ñ¨M¤§¹D¡G
¡@
µù1.
¡@ |
¥Ñ©ó DLL ª©¥»ªº§ó·s¥i¯à¨Ï±o쥻¥s¥Î¥¦ªºµ{¦¡µLªk¥¿±`¹B§@¡A¦]¦¹¥H¤£¦PªºÀɦW°Ï¤Àª©¥»¡]¨Ò¦p¡GMFCxx.DLL¡^¡A¨Ï±oµwºÐ¸Ì±¥²¶·«O¦s¦P¤@ºØ DLL ªº¦hÓª©¥»¡A§Y¨Ï¨Ï¥ÎªÌ±NÀ³¥Îµ{¦¡²¾°£¤F¡A«o¤£´±©ñ¤ßªº²¾°£¬ÛÃöªº DLL ÀɮסA¥H§K¨ä¥LÀ³¥Îµ{¦¡¦]¬°¯Ê¤Ö¤F³oÓÀɮצӵLªk¹B§@¡A³oºØ±¡ªp©Ò§Î¦¨ªº°ÝÃDºÙ¬° DLL hell¡CCOM ªº¥X²{¦³¸Ñ¨M¦¹°ÝÃDªº¥ø¹Ï¡]³z¹L°õ¦æ®É´Á¸ß°Ý¤¸¥ó¤ä´©ªº¤¶±¡^¡A¦ý¦ü¥G¨Ã¤£²z·Q¡Aª½¨ì .NET ªº°Ý¥@¦Ó²×©ó¦³¤F¤ñ¸û¦nªº¸Ñ¨M¤è®×¡C |
µù2. | ¥i¥H¨ì http://www.geocities.com/huanlin_tsai/ ªº¡e¤ß±o¤À¨É¡f°Ï§ä¨ì¬ÛÃö¤å³¹¡C¤£¥i¿Ð¨¥¡A¥H¤W©Ò»¡ªºÃø§KºUÂø¤FÓ¤Hªº¦]¯À¡A¤]³\¨ä¥L¤H¦b¨Ï¥Î package ®É¨Ã¥¼µo¥Í¤Wz°ÝÃD¡A¦Ó¥B¨Ï¥Î package ªº¤è¦¡¤]¦³³\¦hÀuÂI¡A¦b¦¹¶È±NÓ¤H¹ê»ÚÀ³¥Î®Éªºª¬ªp»P·Pı´yz¥X¨Ó¡AY¦³ÂÕ»~¤§³B©|½Ð¦U¤è¤£§[«ü¥¿¡C |
µù3. | Singleton ¼Ë¦¡¡G´£¨Ñ³æ¤@µ¡¤f¨Ó«Ø¥ßÃþ§Oªº¹êÅé¡A¥H½T«O¥u¦³¤@ÓÃþ§Oªº¹êÅé¦s¦b¡C°Ñ¦Ò [GHJV95] ªº®Ñ¡C |