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

首頁 > 編程 > Delphi > 正文

插件管理框架 for Delphi(二)

2020-01-31 20:52:35
字體:
來源:轉載
供稿:網友
unit untDllManager;

interface

uses
  Windows, Classes, SysUtils, Forms;

type

  EDllError = Class(Exception);

  TDllClass = Class of TDll;
  TDll = Class;

  TDllEvent = procedure(Sender: TObject; ADll: TDll) of Object;

  { TDllManager
    o 提供對 Dll 的管理功能; 
    o Add 時自動創建 TDll 對象,但不嘗試裝載;
    o Delete 時自動銷毀 TDll 對象;
  }

  TDllManager = Class(TList)
  private
    FLock: TRTLCriticalSection;
    FDllClass: TDllClass;
    FOnDllLoad: TDllEvent;
    FOnDllBeforeUnLoaded: TDllEvent;
    function GetDlls(const Index: Integer): TDll;
    function GetDllsByName(const FileName: String): TDll;
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  public
    constructor Create;
    destructor Destroy; override;
    function Add(const FileName: String): Integer; overload;
    function IndexOf(const FileName: String): Integer; overload;
    function Remove(const FileName: String): Integer; overload;
    procedure Lock;
    procedure UnLock;
    property DllClass: TDllClass read FDllClass write FDllClass;
    property Dlls[const Index: Integer]: TDll read GetDlls; default;
    property DllsByName[const FileName: String]: TDll read GetDllsByName;
    property OnDllLoaded: TDllEvent read FOnDllLoad write FOnDllLoad;
    property OnDllBeforeUnLoaded: TDllEvent read FOnDllBeforeUnLoaded write FOnDllBeforeUnLoaded;
  end;

  { TDll
    o 代表一個 Dll, Windows.HModule
    o 銷毀時自動在 Owner 中刪除自身;
    o 子類可通過覆蓋override DoDllLoaded, 以及DoDllUnLoaded進行功能擴展;
  }

  TDll = Class(TObject)
  private
    FOwner: TDllManager;
    FModule: HMODULE;
    FFileName: String;
    FPermit: Boolean;
    procedure SetFileName(const Value: String);
    function GetLoaded: Boolean;
    procedure SetLoaded(const Value: Boolean);
    procedure SetPermit(const Value: Boolean);
  protected
    procedure DoDllLoaded; virtual;
    procedure DoBeforeDllUnLoaded; virtual;
    procedure DoDllUnLoaded; virtual;
    procedure DoFileNameChange; virtual;
    procedure DoPermitChange; virtual;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    function GetProcAddress(const Order: Longint): FARPROC; overload;
    function GetProcAddress(const ProcName: String): FARPROC; overload;
    property FileName: String read FFileName write SetFileName;
    property Loaded: Boolean read GetLoaded write SetLoaded;
    property Owner: TDllManager read FOwner;
    property Permit: Boolean read FPermit write SetPermit;
  end;

implementation

{ TDll }

constructor TDll.Create;
begin
  FOwner := nil;
  FFileName := ´´;
  FModule := 0;
  FPermit := True;
end;

destructor TDll.Destroy;
var
  Manager: TDllManager;
begin
  Loaded := False;
  if FOwner <> nil then
  begin
    //在擁有者中刪除自身
    Manager := FOwner;
    //未防止在 TDllManager中重復刪除,因此需要將
    //FOwner設置為 nil; <-- 此段代碼和 TDllManager.Notify 需要配合
    //才能確保正確。 
    FOwner := nil;
    Manager.Remove(Self);
  end;
  inherited;
end;

function TDll.GetLoaded: Boolean;
begin
  result := FModule <> 0;
end;

function TDll.GetProcAddress(const Order: Longint): FARPROC;
begin
  if Loaded then
    result := Windows.GetProcAddress(FModule, Pointer(Order))
  else
    raise EDllError.CreateFmt(´Do Load before GetProcAddress of "%u"´, [DWORD(Order)]);
end;

function TDll.GetProcAddress(const ProcName: String): FARPROC;
begin
  if Loaded then
    result := Windows.GetProcAddress(FModule, PChar(ProcName))
  else
    raise EDllError.CreateFmt(´Do Load before GetProcAddress of "%s"´, [ProcName]);
end;

procedure TDll.SetLoaded(const Value: Boolean);
begin
  if Loaded <> Value then
  begin
    if not Value then
    begin
      Assert(FModule <> 0);
      DoBeforeDllUnLoaded;
      try
        FreeLibrary(FModule);
        FModule := 0;
      except
        Application.HandleException(Self);
      end;
      DoDllUnLoaded;
    end
    else
    begin
      FModule := LoadLibrary(PChar(FFileName));
      try
        Win32Check(FModule <> 0);
        DoDllLoaded;
      except
        On E: Exception do
        begin
          if FModule <> 0 then
          begin
            FreeLibrary(FModule);
            FModule := 0;
          end;
          raise EDllError.CreateFmt(´LoadLibrary Error: %s´, [E.Message]);
        end;
      end;
    end;
  end;
end;

procedure TDll.SetFileName(const Value: String);
begin
  if Loaded then
    raise EDllError.CreateFmt(´Do Unload before load another Module named: "%s"´,
      [Value]);
  if FFileName <> Value then
  begin
    FFileName := Value;
    DoFileNameChange;
  end;
end;

procedure TDll.DoFileNameChange;
begin
  // do nonthing.
end;

procedure TDll.DoDllLoaded;
begin
  if Assigned(FOwner) and Assigned(FOwner.OnDllLoaded) then
    FOwner.OnDllLoaded(FOwner, Self);
end;

procedure TDll.DoDllUnLoaded;
begin
  //do nonthing.
end;

procedure TDll.DoPermitChange;
begin
  //do nonthing.
end;

procedure TDll.SetPermit(const Value: Boolean);
begin
  if FPermit <> Value then
  begin
    FPermit := Value;
    DoPermitChange;
  end;
end;

procedure TDll.DoBeforeDllUnLoaded;
begin
  if Assigned(FOwner) and Assigned(FOwner.OnDllBeforeUnLoaded) then
    FOwner.OnDllBeforeUnLoaded(FOwner, Self);
end;

{ TDllManager }

function TDllManager.Add(const FileName: String): Integer;
var
  Dll: TDll;
begin
  result := -1;
  Lock;
  try
    if DllsByName[FileName] = nil then
    begin
      Dll := FDllClass.Create;
      Dll.FileName := FileName;
      result := Add(Dll);
    end
    else
      result := -1;
  finally
    UnLock;
  end;
end;

constructor TDllManager.Create;
begin
  FDllClass := TDll;
  InitializeCriticalSection(FLock);
end;

destructor TDllManager.Destroy;
begin
  DeleteCriticalSection(FLock);
  inherited;
end;

function TDllManager.GetDlls(const Index: Integer): TDll;
begin
  Lock;
  try
    if (Index >=0) and (Index <= Count - 1) then
      result := Items[Index]
    else
      raise EDllError.CreateFmt(´Error Index of GetDlls, Value: %d, Total Count: %d´, [Index, Count]);
  finally
    UnLock;
  end;
end;

function TDllManager.GetDllsByName(const FileName: String): TDll;
var
  I: Integer;
begin
  Lock;
  try
    I := IndexOf(FileName);
    if I >= 0 then
      result := Dlls[I]
    else
      result := nil;
  finally
    UnLock;
  end;
end;

function TDllManager.IndexOf(const FileName: String): Integer;
var
  I: Integer;
begin
  result := -1;
  Lock;
  try
    for I := 0 to Count - 1 do
      if CompareText(FileName, Dlls[I].FileName) = 0 then
      begin
        result := I;
        break;
      end;
  finally
    UnLock;
  end;
end;

procedure TDllManager.Lock;
begin
  OutputDebugString(Pchar(´TRLock DM´ + IntToStr(GetCurrentThreadId) + ´:´ + IntToStr(DWORD(Self))));
  EnterCriticalSection(FLock);
  OutputDebugString(Pchar(´Locked DM´ + IntToStr(GetCurrentThreadId) + ´:´ + IntToStr(DWORD(Self))));
end;

procedure TDllManager.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if Action = lnDeleted then
  begin
    //若TDll(Ptr).Owner和Self不同,則
    //表明由 TDll.Destroy 觸發;
    if TDll(Ptr).Owner = Self then
    begin
      //防止FOwner設置為nil之后相關事件不能觸發
      TDll(Ptr).DoBeforeDllUnLoaded;
      TDll(Ptr).FOwner := nil;
      TDll(Ptr).Free;
    end;
  end
  else
  if Action = lnAdded then
    TDll(Ptr).FOwner := Self;
  inherited;
end;

function TDllManager.Remove(const FileName: String): Integer;
var
  I: Integer;
begin
  result := -1;
  Lock;
  try
    I := IndexOf(FileName);
    if I >= 0 then
      result := Remove(Dlls[I])
    else
      result := -1;
  finally
    UnLock;
  end;
end;

procedure TDllManager.UnLock;
begin
  LeaveCriticalSection(FLock);
  OutputDebugString(Pchar(´UnLock DM´ + IntToStr(GetCurrentThreadId) + ´:´ + IntToStr(DWORD(Self))));
end;

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

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性猛交xxxx乱大交| 欧美一乱一性一交一视频| 亚洲欧美在线x视频| 欧美激情精品久久久久| 欧美大全免费观看电视剧大泉洋| 国内免费久久久久久久久久久| 久久精品福利视频| 不卡av日日日| 亚洲精品一区久久久久久| 久久人人爽人人爽人人片亚洲| www.国产精品一二区| 亚洲色图五月天| 亚洲视频在线观看免费| 国产精品久久久久久av福利| 久久人人97超碰精品888| 亚洲人精选亚洲人成在线| 亚洲欧美制服中文字幕| 亚洲天堂第二页| 欧美激情久久久久| 欧美激情乱人伦一区| 亚洲女人天堂网| 高清亚洲成在人网站天堂| 亚洲国产精品一区二区久| 亚洲精品白浆高清久久久久久| 高清欧美电影在线| 国产免费一区二区三区在线观看| 欧美视频中文字幕在线| 亚洲第一视频在线观看| 国产精品久久久久久久久久久久| 久久久久久久久91| 日韩小视频在线| 国产精品久久久久久av| 美乳少妇欧美精品| 国产精品视频在线观看| 国产成人精品优优av| 国产精品美女www| 亚洲欧美日韩成人| 国产成人极品视频| 欧美丰满老妇厨房牲生活| 精品国产一区二区三区久久| 日韩欧美精品中文字幕| 欧美精品电影免费在线观看| 午夜精品久久久久久99热软件| 一本色道久久88综合亚洲精品ⅰ| 成人网页在线免费观看| 97在线视频免费播放| 91在线视频免费| 欧美体内谢she精2性欧美| 亚洲欧美成人在线| 国产精品久久久久免费a∨大胸| 91香蕉嫩草神马影院在线观看| 91精品视频在线| 久久亚洲精品成人| 久久久999精品| 68精品久久久久久欧美| 国产+成+人+亚洲欧洲| 国产精品成人国产乱一区| 91欧美激情另类亚洲| 欧美激情精品久久久久久蜜臀| 精品久久久久久久久久久久久久| 91视频免费在线| 国产综合在线视频| 中文字幕精品www乱入免费视频| 性日韩欧美在线视频| 日韩有码在线播放| 日韩欧美国产成人| 日韩中文字幕视频在线| 久久激情视频免费观看| 日韩在线视频免费观看| 青青a在线精品免费观看| 国产精品毛片a∨一区二区三区|国| 欧美一区二区三区精品电影| 久久免费福利视频| 色777狠狠综合秋免鲁丝| 亚洲国产女人aaa毛片在线| 日本精品va在线观看| 伊人伊成久久人综合网小说| 欧美网站在线观看| 日韩一二三在线视频播| 日韩av成人在线观看| 黄色一区二区在线观看| 欧美午夜精品久久久久久人妖| 欧美一乱一性一交一视频| 欧美亚洲成人精品| 日韩视频免费在线观看| 日韩在线观看视频免费| 欧美一区二区视频97| 日韩在线免费av| 精品成人乱色一区二区| 久久久精品国产一区二区| 亚洲成av人片在线观看香蕉| 国产精品视频网| 亚洲男女自偷自拍图片另类| 欧美性xxxx极品高清hd直播| 亚洲欧美国产一区二区三区| 欧美另类在线观看| 91欧美日韩一区| 亚洲国产精品久久久久秋霞蜜臀| 久久精品99久久香蕉国产色戒| 国产亚洲精品综合一区91| 国产精品爱久久久久久久| 国产精品久久久久国产a级| 亚洲国产精彩中文乱码av| 欧美精品免费在线观看| 日韩电视剧在线观看免费网站| 91视频国产一区| 欧美在线视频一区| 欧美日韩另类视频| 亚洲精品福利视频| 亚洲激情视频在线播放| 尤物精品国产第一福利三区| 国产精品国产福利国产秒拍| 欧美一区二区影院| 一本大道香蕉久在线播放29| 国产精品极品尤物在线观看| 国产精品一香蕉国产线看观看| 亚洲精品福利视频| 国内精品国产三级国产在线专| 伦理中文字幕亚洲| 国产人妖伪娘一区91| 欧美精品在线播放| 精品久久久久久久大神国产| www.欧美视频| 久久久久这里只有精品| 91国产精品电影| 亚洲a一级视频| 97精品伊人久久久大香线蕉| 亚洲第一区中文字幕| 亚洲欧美制服第一页| 欧美激情一区二区三区在线视频观看| 68精品国产免费久久久久久婷婷| 欧美一级电影免费在线观看| 国产成人精品综合| 91超碰caoporn97人人| 国产视频精品xxxx| 欧美视频在线观看免费网址| 亚洲一区制服诱惑| 国产精品一区av| 亚洲最大的免费| 亚洲丁香婷深爱综合| 久久精品影视伊人网| 97超级碰碰碰| 91日韩在线播放| 亚洲aa中文字幕| 日本精品视频在线观看| 久久国产精品99国产精| 欧美体内谢she精2性欧美| 91免费综合在线| 欧美一级大片在线免费观看| 国产婷婷成人久久av免费高清| 中文字幕免费国产精品| 国自产精品手机在线观看视频| 久久久久久久久久婷婷| 国产精品美女www爽爽爽视频| 欧洲成人在线视频| 亚洲电影免费在线观看| 国产精品久久久久久亚洲调教| 久久久久久久一区二区| 永久免费毛片在线播放不卡| 欧美在线视频免费观看| 91在线免费视频| 欧美日韩国产中文精品字幕自在自线| 琪琪亚洲精品午夜在线| 国产精品久在线观看|