亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

Delphi 插件創建、調試與使用應用程序擴展

2019-11-17 05:09:24
字體:
來源:轉載
供稿:網友

  有沒有使用過Adobe photoshop假如用過,你就會對插件的概念比較熟悉。對外行人來說,插件僅僅是從外部提供給應用程序的代碼塊而已(舉個例子來說,在一個DLL中)。一個插件和一個普通DLL之間的差異在于插件具有擴展父應用程序功能的能力。
例如,Photoshop本身并不具備進行大量的圖像處理功能。插件的加入使其獲得了產生諸如模糊、斑點,以及其他所有風格的希奇效果,而其中任何一項功能都不是父應用程序自身所具有的。
  對于圖像處理程序來說這很不錯,可是為什么要花偌大的力氣去完成支持插件的商業應用程序呢?假設,我們舉個例子,你的應用程序要產生一些報表。你的客戶肯定會一直要求更新或者增加新的報表。你可以使用一個諸如Report Smith的外部報表生成器,這是個不怎么樣的解決方案,需要發布附加的文件,要對用戶進行額外的培訓,等等。你也可以使用QuickReport,不過這會使你身處版本控制的噩夢之中——假如每改變一次字體你就要Rebuild你的應用程序的話。
  然而,只要你把報表做到插件中,你就可以使用它。需要一個新的報表嗎?沒問題,只要安裝一個DLL,下次應用程序啟動時就會看見它了。另外一個例子是處理來自外部設備(比如條形碼掃描器)的數據的應用程序,為了給用戶更多的選擇,你不得不支持半打的各種設備。通過將每種設備接口處理例程寫成插件,不用對父應用程序作任何變動就可以獲得最大程度的可伸縮性。

入門

  在開始寫代碼之前最重要的事情就是搞清楚你的應用程序到底需要擴展哪些功能。這是因為插件是通過一個特定的接口與父應用程序交互的,而這個接口將根據你的需要來定義。在本文中,我們將建立3個插件,以便展示插件與父應用程序相交互的幾種方式。
  我們將把插件制作成DLL。不過,在做這項工作之前,我們得先制作一個外殼程序來載入和測試它們。圖1顯示的是加載了第一個插件以后的測試程序。第一個插件沒有完成什么大不了的功能,實際上,它所做的只是返回一個描述自己的字符串。不過,它證實了很重要的一點——不管有沒有插件應用程序都可以正常運行。假如沒有插件,它就不會出現在已安裝的插件列表中,但是應用程序仍然可以正常的行使功能。

  我們的插件外殼程序與普通應用程序之間的唯一不同就在于工程源文件中出現在uses子句中的Sharemem單元和加載插件文件的代碼。任何在自身與子DLL之間傳遞字符串參數的應用? 都需要Sharemem單元,它是DelphiMM.dll(Delphi提供該文件)的接口。要測試這個外殼,需要將DelphiMM.dll文件從Delphi/Bin目錄復制到path環境變量所包含的路徑或者應用程序所在目錄中。發布最終版本時也需要同時分發該文件。
插件通過LoadPlugins過程載入到這個測試外殼中,這個過程在主窗口的FormCreate事件中調用,見圖2。該過程使用FindFirst和FindNext函數在應用程序所在目錄中查找插件文件。找到一個文件以后,就使用圖3所示的LoadPlugins過程將其載入。
{ 在應用程序目錄下查找插件文件 }
PRocedure TfrmMain.LoadPlugins;
var
  sr: TSearchRec;
  path: string;
  Found: Integer;
begin
  path := ExtractFilePath(application.Exename);
  try
  Found := FindFirst(path + cPLUGIN_MASK, 0, sr);
  while Found = 0 do begin
  LoadPlugin(sr);
  Found := FindNext(sr);
end;
  finally
  FindClose(sr);
end;
end;


{ 加載指定的插件 DLL. }
procedure TfrmMain.LoadPlugin(sr: TSearchRec);
var
  Description: string;
  LibHandle: Integer;
  DescribeProc: TPluginDescribe;
begin
  LibHandle := LoadLibrary(Pchar(sr.Name));
  if LibHandle $#@60;$#@62; 0 then
begin
  DescribeProc := GetProcAddress(LibHandle, cPLUGIN_DESCRIBE);
if Assigned(DescribeProc) then

begin
 DescribeProc(Description);
 memPlugins.Lines.Add(Description);
end
else
begin
 MessageDlg(’File "’ + sr.Name +’" is not a valid plug-in.’,
mtInformation, [mbOK], 0);
end;
end
else
MessageDlg(’An error occurred loading the plug-in "’ +
sr.Name + ’".’, mtError, [mbOK], 0);
end;


  LoadPlugin方法展示了插件機制的核心。首先,插件被寫成DLL。其次,通過LoadLibrary API它被動態的加載。一旦DLL被加載,我們就需要一個訪問它所包含的過程和函數的途徑。API調用GetProcAddress提供這種機制,它返回一個指向所需例程的指針。在我們這個簡單的演示中,插件僅僅包含一個名為DescribePlugin的過程,由常數cPLUGIN_DESCRIBE指定(過程名的大小寫非常重要,傳遞到GetProcAddress的名稱必須與包含在DLL中的例程名稱完全一致)。假如在DLL中沒有找到請求的例程,GetProcAddree將返回nil,這樣就答應使用Assigned函數測定返回值。
  為了以一種易用的方式存儲指向一個函數的指針,有必要為用到的變量創建一個特定的類型。注重,GetProcAddress的返回值被存儲在一個變量中,DescribeProc,屬于TpluginDescribe類型。下面是它的聲明:
type
TPluginDescribe = procedure(var Desc: string); stdcall;
  由于過程存在于DLL內部,它通過標準調用轉換編譯所有導出例程,因此需要使用stdcall指示字。這個過程使用一個var參數,當過程返回的時候它包含插件的描述。
  要調用剛剛獲得的過程,只需要使用保存地址的變量作為過程名,后面跟上任何參數。就我們的例子而言,聲明:
DescribeProc(Description)
  將會調用在插件中獲得的描述過程,并且用描述插件功能的字符串填充Description變量。

構造插件

  我們已經創建好了父應用程序,現在該輪到創建我們希望加載的插件了。插件文件是一個標準的Delphi DLL,所以我們從Delphi IDE中創建一個新DLL工程,保存它。由于導出的插件函數將用到字符串參數,所以要在工程的uses子句中把Sharemen單元放在最前面。圖4列出的就是我們這個簡單插件的工程源文件。
uses
Sharemem, SysUtils, Classes,
main in ’main.pas’;

{$E plg.}

eXPorts
DescribePlugin;

begin

end.


  雖然插件是一個DLL文件,但是沒有必要一定要給它一個.DLL的擴展名。實際上,一個原因就足以讓我們有理由改變擴展名:當父應用程序尋找要加載的文件時,新的擴展名可以作為特定的文件掩模。通過使用別的擴展名(我們的例子使用了*.plg),你可以在一定程度上確信應用程序只會載入相應的文件。編譯指示字$X可以實現這個改變,也可以通過Project Options對話框的Application頁來設置擴展名。
  第一個例子插件的代碼是很簡單的。圖5顯示了包含在一個新單元中的代碼。注重,DescribePlugin原型與外殼應用程序中的TpluginDescribe類型相一致,使用附加的export保留字指定該過程將被導出。被導出的過程名稱也將會出現在主工程源代碼的exports段中(在圖4中列出)。
unit main;

interface

procedure DescribePlugin(var Desc: string);
export; stdcall;

implementation

procedure DescribePlugin(var Desc: string);
begin
Desc := ’Test plugin v1.00’;
end;

end.


  在測試這個插件之前,要先把它復制到主應用程序的路徑下。最簡單的辦法就是在主目錄的子目錄下創建插件,然后把輸出路徑設置為主路徑(Project Options對話框的Directories/Conditionals也可以作這個設置)。

調試

  現在介紹一下Delphi 3中一個較好的功能:從IDE中調試DLL的能力。在DLL工程中可以通過Run paramaters對話框指定某程序為宿主應用程序,這就是指向將調用DLL的應用程序的路徑(在我們這個例子中,就是剛剛創建的測試外殼程序)。然后你就可以在DLL代碼中設置斷點并且按F9運行它——就像在一個普通應用程序中做的那樣。Delphi會運行指定的宿主程序,并且,通過編譯帶有調試信息的DLL,把你指引到DLL代碼內的斷點處。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美极品欧美精品欧美视频| 91香蕉国产在线观看| 国产一区二区激情| 国产高清视频一区三区| 91精品国产91久久久久久最新| 日韩在线视频二区| 亚洲日韩中文字幕| 国产精品日韩欧美综合| 91在线视频成人| 欧美激情视频网址| 亚洲女人天堂成人av在线| 欧美理论电影在线播放| 久久资源免费视频| 日本a级片电影一区二区| 中文字幕亚洲欧美日韩高清| 久色乳综合思思在线视频| 国产精品极品美女在线观看免费| 欧美专区日韩视频| 亚洲在线视频观看| 色狠狠久久aa北条麻妃| 超碰日本道色综合久久综合| 日韩免费观看在线观看| 午夜精品久久久久久久久久久久久| 亚洲精品一区久久久久久| 国产这里只有精品| 成人激情视频免费在线| 国产日产亚洲精品| 97在线视频观看| 久久成人一区二区| 中文字幕无线精品亚洲乱码一区| 久久久国产91| 色婷婷久久av| 午夜精品美女自拍福到在线| 欧美电影院免费观看| 亚洲天堂视频在线观看| 亚洲小视频在线| 日韩av在线免费播放| 欧美国产亚洲精品久久久8v| www.欧美精品| 亚洲国产成人在线视频| 日韩欧美国产视频| 777国产偷窥盗摄精品视频| 日韩中文字幕不卡视频| 日韩av最新在线观看| 国产精品中文字幕在线| 91亚洲精品一区二区| 久久久亚洲成人| 国产精品久久久久久久9999| 国产三级精品网站| 日韩视频在线观看免费| 主播福利视频一区| 欧美野外wwwxxx| 亚洲欧美日韩爽爽影院| 色yeye香蕉凹凸一区二区av| 久久久久久12| 亚洲乱码av中文一区二区| 久久综合免费视频影院| 国产精品久久久久久久午夜| 欧美成人h版在线观看| 久久久精品亚洲| 亚洲国产欧美一区| 超薄丝袜一区二区| 亚洲欧美一区二区激情| 亚洲一区二区三区四区在线播放| 日韩成人在线视频观看| 91久久久精品| 中文字幕日韩欧美精品在线观看| 97香蕉久久超级碰碰高清版| 国内精品400部情侣激情| 日韩电影在线观看免费| 日韩人在线观看| 日韩禁在线播放| 91中文字幕一区| 国产精品黄视频| 国产女精品视频网站免费| 国产精品极品尤物在线观看| 欧美另类高清videos| 欧美性受xxxx白人性爽| 亚洲加勒比久久88色综合| 国产日韩亚洲欧美| 午夜精品久久久久久久99热| 日韩欧美在线看| 欧美一级片久久久久久久| 91产国在线观看动作片喷水| 国产精品久久久久久久久久小说| 一本色道久久88综合亚洲精品ⅰ| 成人国内精品久久久久一区| 91精品久久久久久综合乱菊| 国产精品亚洲精品| 亚洲人高潮女人毛茸茸| 久久在线观看视频| 欧洲日本亚洲国产区| 91免费电影网站| 欧美高清在线观看| 亚洲天堂av综合网| 欧美在线观看网址综合| 中文国产成人精品| 欧美成人合集magnet| 日本精品免费观看| 国产精品视频白浆免费视频| 精品国产一区二区三区久久久狼| 国产精品免费一区二区三区都可以| 日韩电视剧在线观看免费网站| 成人av在线网址| 久久久亚洲影院| 日韩精品极品在线观看| 亚洲日本中文字幕免费在线不卡| 一区二区成人精品| 色爱av美腿丝袜综合粉嫩av| 亚洲午夜精品久久久久久性色| 欧美性做爰毛片| 日韩av影视综合网| 久久成年人免费电影| 中文字幕亚洲欧美一区二区三区| 国产精品三级久久久久久电影| 欧美日韩另类在线| 国产一区二区三区在线观看视频| 国产极品jizzhd欧美| 成人两性免费视频| 欧美激情视频一区| 久久久精品国产一区二区| 伊人男人综合视频网| 51精品在线观看| 国产精品爽黄69| 成人乱人伦精品视频在线观看| 亚洲美女自拍视频| 久久久久久久久久婷婷| 日韩av免费观影| 国产网站欧美日韩免费精品在线观看| 欧美精品videos性欧美| 久久久免费av| 亚洲美女av电影| 久久久亚洲国产| 热re91久久精品国99热蜜臀| 欧美电影电视剧在线观看| 福利视频导航一区| 欧美日韩国产一区二区三区| 性欧美亚洲xxxx乳在线观看| 久久视频这里只有精品| 91社区国产高清| 国产精品久久久久久av下载红粉| 亚洲free嫩bbb| 久久精品国产一区二区电影| 亚洲国产精品成人va在线观看| 国产精品日韩久久久久| 日韩免费观看网站| 欧美国产日韩精品| 久久久久久久久亚洲| 国产精品电影网| 亚洲国产天堂久久综合| 国产精品免费网站| 亚洲国产精久久久久久| 欧美激情a∨在线视频播放| 欧美成人一区二区三区电影| 国产精品亚洲网站| 亚洲欧美国产一本综合首页| 精品国产乱码久久久久久天美| 91精品久久久久久久久久久久久| 久久精品亚洲94久久精品| 成人福利网站在线观看| 日韩av网站大全| 亚洲午夜国产成人av电影男同| 亚洲成人av片在线观看| 日韩福利伦理影院免费|