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

首頁 > 編程 > Delphi > 正文

Dll中導出類--Delphi實戰之一

2019-11-18 18:45:02
字體:
來源:轉載
供稿:網友

更新歷史:No.1

更新時間:2001-11-01 20:09

更新人員:Musicwind®

更新備注:初稿完成。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

摘要:

本文討論的是如何在Dll中導出類――基于某個特定的抽象類的許多子類。這種技術運用了多態的思想,使得我們得到類似于插件的效果。

預期讀者:

了解多態的概念;了解元類的概念。

技術難度:

6/10。

 

Dll中導出類,想必大家首先想到的是使用bpl包。這種方式有一個不好,那就是使用者必須清楚這個包中含有那些類,也就是說必須知道類的名字――這在一定意義上是個限制,試想一種情況,使用者定義了一個底層的抽象類(abstract class),然后在此基礎上定義了許多應用類(concrete class),那么,對于使用者來說,他希望在不知道具體有哪些類的情況下能使用這些類――這么說似乎有些玄,但實際情況確實如此,因為定義抽象類的時候并不能預料到以后會有多少個具體類――那么這樣的需求,要靠什么樣的技術來實現呢?

       其實實現的技術的難度并不大――作者在此將自己實踐的經驗獻給大家,算作拋磚引玉,希望能看到其他更好的方法!

       以下先介紹該方法涉及的一些基礎知識,然后用一個例子來說明具體的實現。

一、基本概念

       元類(meta class),也叫類引用類型(class-reference type),可以看成是一種類的類型,以該類型聲明的變量的值代表一個類。比如:

       type

         TClass = Class of TObject;

這樣就聲明了一個元類的類型。然后可以有這樣的變量聲明:

Var

  AClass: TClass;

那么,就可以有這樣的用法:

AClass := TObject;

或者:

AClass := TButton;

或者:

AClass := TForm;

等等。

因為TClass是一個TObject類型的元類,而TButton,TForm等都是自TObject派生而來,因而TButtonTForm這樣的值對于AClass都是可接受的。

然后,我們就可以運用多態的思想,靈活運用AClass這個類變量了。而這一點也正是下文具體實現的基礎知識。

二、具體實現

       第一步,建立一個抽象類:

       我們使用這樣一個簡單的聲明,該抽象類只提供了一種抽象方法,但并不影響我們描述問題:

TMyBaseForm = Class(TForm)

      PRotected

function GetTitle: pchar; virtual; abstract;

      end;

       MyBaseFormClass = Class of TMyBaseForm;

       暫不探討這么一個抽象類提供了多少可供實用的方法和接口,因為我們要討論的是一種技術上的可行性。假設作者定義此接口的初衷只是希望獲得任意多變化的Title,而具體GetTitle的返回值是什么需要靠子類來實現。并且,作者還希望子類的代碼放在Dll中實現,與主程序分離――這樣的方式很有些插件的味道,或許還能實現Plug&Play的某些特性――是不是挺吸引人啊?那么,下一不應該怎么做呢?

       首先主程序和Dll程序應當將上述聲明的單元包含進來,然后,主程序負責實現一個驅動――動態加載Dll,動態加載類;而Dll負責實現子類。

       先說Dll吧,Dll應當做什么工作?

第二步,Dll中導出子類:

我們設計了以下兩個導出函數:

1.  function GetClassCount: integer; stdcall;

告訴調用者,本Dll中共有幾個子類;

2function GetClassTypeByIndex(const iIndex: integer;

  var ClassType: MyBaseFormClass): WordBool; stdcall;

以索引方式獲得具體的子類。注意,此處的ClassType的類型是MyBaseFormClass,這表明,它的值將是一個確定的自TMyBaseForm繼承而來的類。

以下是它們可能的一種實現:

function GetClassCount: integer;

begin

  result := 3; //表明本Dll中導出了3個類

end;

 

function GetClassTypeByIndex(const iIndex: integer;

  var ClassType: MyBaseFormClass): WordBool;

begin

  result := True;

  case iIndex of

    0: ClassType := TFrmTest1;

       1: ClassType := TFrmTest2;

       2: ClassType := TFrmTest3;

    else

      result := False;

  end;

end;

       當然,在該單元的Use列表中應當將TFrmTest1TFrmTest2以及TFrmTest3所在的單元包含進來。而TFrmTest1的實現可以象這樣:

       TFrmTest1 = Class(TMyBaseForm)

       protected

function GetTitle: PChar; override;

end;

function TFrmTest1.GetTitle: Pchar;

begin

  result := ‘Hello from TFrmTest1’

end;

       末了,別忘了將GetClassCountGetClassByIndex加到Exports列表中。然后,BuildDll工程的時候,請將Project option-package 中的使用運行包use runtime package”打勾。至于具體的原因后面講。

至此,Dll方面的工作告一段落。

       第三步,主程序驅動引擎的實現:

       這一步相對來說容易些――無非是動態加載Dll,然后調用GetClassCount函數,接著調用GetClassByIndex。關鍵的代碼:

       Var AClass: TMyBaseClass;

       AForm: TMyBaseForm;

I, iCount: integer;

blResult: Boolean;

begin

  //略去加載動態庫的部分,假定FPGetClassProc指向GetClassCount函數,FPGetClassByIndexProc指向GetClassByIndex,則:

  iCount := FPGetClassProc;

  for I := 0 to iCount ?C 1 do

  begin

    AClass := FPGetClassByIndex(I, blResult);

       if blResult then

    begin

      AForm := AClass.Create(application);

      AForm.Caption := AForm.GetTitle;

      AForm.Show;

    end;

  end;

//…

end;

       注意一點,和Dll相似,創建輸出文件的時候,也需要選擇使用運行時間包。這是因為,如果不使用運行時間包,將導致相同的類在內存中有多個副本,因而對它們使用Is操作符的將返回False的結果。

 

Musicwind®@HangZhou.Zhejiang.China

2001-11-01

更多文章

[文終]


上一篇:設計模式、用Delphi實現---->Builder模式

下一篇:設計模式、用Delphi描述-->Observer模式

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲a在线观看| 成人免费看黄网站| 91久久久久久久久久久久久| 大量国产精品视频| 久久精品国产69国产精品亚洲| 中文字幕无线精品亚洲乱码一区| 久久综合九色九九| 日韩av在线直播| 97在线观看视频国产| 久久久国产在线视频| xxav国产精品美女主播| 久久亚洲精品视频| 国产欧美一区二区三区久久人妖| 成人精品aaaa网站| 亚洲人成亚洲人成在线观看| 国产成人高潮免费观看精品| 97视频免费在线观看| 97在线精品视频| 日韩视频永久免费观看| 久久手机免费视频| 亚洲欧美精品一区| 91精品在线国产| 久久久女女女女999久久| 国产脚交av在线一区二区| 日韩女优在线播放| 亚洲精品美女久久| 亚洲自拍高清视频网站| 91精品啪在线观看麻豆免费| 国产丝袜视频一区| 一区二区日韩精品| 国产精品久久久久久久久久久不卡| 成人欧美一区二区三区黑人| 色综合久久久久久中文网| 日本在线精品视频| 正在播放欧美视频| 欧美在线视频导航| 一区二区三区天堂av| 亚洲社区在线观看| 欧美日韩中文字幕在线视频| 中国日韩欧美久久久久久久久| 亚洲高清久久久久久| 国产一区二区三区高清在线观看| 欧美成人午夜剧场免费观看| 精品电影在线观看| 亚洲九九九在线观看| 亚洲欧洲午夜一线一品| 国产极品jizzhd欧美| 欧美日韩美女视频| 97精品国产97久久久久久| 91国自产精品中文字幕亚洲| 成人在线视频福利| 国产精品福利无圣光在线一区| 欧美日韩ab片| 久久久亚洲精品视频| 精品一区电影国产| 欧美日韩一区二区三区| 久久精视频免费在线久久完整在线看| 成人午夜激情免费视频| 久久久91精品国产一区不卡| 国产亚洲美女精品久久久| 亚洲免费小视频| 亚洲人永久免费| 91国产中文字幕| 九九精品在线播放| 亚洲夜晚福利在线观看| 黑人巨大精品欧美一区二区一视频| 97成人精品视频在线观看| 91精品视频免费| 国产精品视频大全| 中文字幕日本欧美| 欧美日韩成人网| 精品电影在线观看| 日韩精品有码在线观看| 中文字幕精品视频| 午夜精品美女自拍福到在线| 91在线视频导航| 国产亚洲视频中文字幕视频| 国产精品女主播| 精品视频www| 亚洲wwwav| 2023亚洲男人天堂| 精品国产一区二区三区久久| 日韩电影在线观看免费| 人人澡人人澡人人看欧美| 亚洲国产精久久久久久| 亚洲国产精品va在线看黑人| 一区二区三区久久精品| 伊人激情综合网| 91精品久久久久久| 日韩欧美精品在线观看| 91精品国产色综合| 国产日产久久高清欧美一区| 青青久久av北条麻妃海外网| 欧美在线性视频| 亚洲字幕在线观看| 日本久久久久久久久| 亚洲视频在线免费看| 日韩美女视频中文字幕| 亚洲国产精品高清久久久| 成人黄色av免费在线观看| 久久久国产视频| 久久久伊人日本| 日韩av免费在线| 精品国产一区二区三区久久狼黑人| 日产日韩在线亚洲欧美| 555www成人网| 一区二区三区无码高清视频| www亚洲精品| 大胆人体色综合| 亚洲国产欧美在线成人app| 精品成人国产在线观看男人呻吟| 91精品国产一区| 欧美日韩亚洲视频| 欧美性极品少妇精品网站| 超碰日本道色综合久久综合| 美女扒开尿口让男人操亚洲视频网站| 国产精品久久久久国产a级| 欧美专区第一页| 亚洲第一区在线观看| 日韩在线观看免费全集电视剧网站| 亚洲欧美日韩直播| 国产69精品久久久久9| 中文字幕自拍vr一区二区三区| 92看片淫黄大片欧美看国产片| 北条麻妃在线一区二区| 日韩av黄色在线观看| 亚洲精品不卡在线| 91精品国产高清久久久久久91| 91av国产在线| 91九色单男在线观看| 亚洲国产精彩中文乱码av| 欧美一区深夜视频| 日韩国产高清视频在线| 欧美极品欧美精品欧美视频| 亚洲成人性视频| 国产精品久久久久av| 久久亚洲精品小早川怜子66| 欧美精品一区三区| 欧美福利视频在线观看| 国产成人在线一区二区| 日本午夜在线亚洲.国产| 精品国产自在精品国产浪潮| 国产一区二区三区在线免费观看| 日韩成人激情在线| 国产a∨精品一区二区三区不卡| 亚洲精品www| 91久久在线观看| 亚洲美女视频网| 国产91|九色| 国产男女猛烈无遮挡91| 亚洲最大av网| 亚洲人午夜精品| 欧美一级片一区| 91视频国产高清| 亚洲国产精品女人久久久| 国产一区二区三区直播精品电影| 欧美精品激情blacked18| 国产精品久久久久av| 色婷婷**av毛片一区| 日韩在线观看精品| 欧美视频13p| 91免费的视频在线播放| 国产亚洲精品一区二区| 亚洲一区av在线播放|