Plugin management framework for Delphi (2)

Source: Internet
Author: User
Tags flock getloaded

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 provides DLL management functions;

O automatically creates a tdll object when adding, but does not try to load it;

O automatically destroys the tdll object during the delete operation;

}

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 week Y (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 represents a DLL, windows. hmodule

O automatically deletes itself from the owner upon destruction;

O sub-classes can be extended by overwriting dodllloaded and 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

// Delete itself from the owner

MANAGER: = fowner;

// It is not prevented from being deleted repeatedly in tdllmanager. Therefore, you need

// Set fowner to nil; <-- this segmentCodeWork with tdllmanager. Notify

// Make sure that it is correct.

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;
snapshot T
application. handleexception (Self);
end;
dodllunloaded;
end
else
begin
fmodule: = loadlibrary (pchar (ffilename ));
try
win32check (fmodule <> 0);
dodllloaded;
T
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;

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. Y (PTR: pointer; Action: tlistnotification );

Begin

If action = lndeleted then

Begin

// If tdll (PTR). Owner is different from self

// Indicates that tdll. Destroy is triggered;

If tdll (PTR). Owner = self then

Begin

// Prevent related events from being triggered after the fowner is set to 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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.