unituntDllManager ;
interface
utilise
Windows, classes, SysUtils, formulaires ;
taper
EDllError=Classe(Exception);
TDllClass=Classe de TDll ;
TDll=Classe;
TDllEvent=procedure(Sender:TObject;ADll:TDll)ofObject;
{TDllManager
o 提供对Dll的管理功能;
oAdd时自动创建TDll对象,但不尝试装载 ;
oSupprimer les fichiers TDll;
}
TDllManager=Classe(TList)
privé
FLLock:TRTLCriticalSection;
FDllClass : TDllClass ;
FOnDllLoad : TDllEvent ;
FOnDllBeforeUnLoaded:TDllEvent;
functionGetDlls(constIndex:Integer):TDll;
functionGetDllsByName(constFileName:String):TDll;
protégé
procédureNotify(Ptr:Pointer;Action:TListNotification);override;
publique
constructeurCréer ;
destructeurDestroy;remplacer;
functionAdd(constFileName:String):Integer;surcharge;
functionIndexOf(constFileName:String):Integer;surcharge;
functionRemove(constFileName:String):Integer;surcharge;
procédureLock ;
procédureUnLock ;
propertyDllClass : TDllClassreadFDllClasswriteFDllClass ;
propertyDlls[constIndex:Integer]:TDllreadGetDlls;par défaut;
propertyDllsByName[constFileName:String]:TDllreadGetDllsByName;
propertyOnDllLoaded : TDllEventreadFOnDllLoadwriteFOnDllLoad ;
propertyOnDllBeforeUnLoaded: TDllEventreadFOnDllBeforeUnLoadedwriteFOnDllBeforeUnLoaded ;
fin;
{TDll
o代表一个Dll,Windows.HModule
o 销毁时自动在Propriétaire中删除自身;
o overrideDoDllLoaded, ou DoDllUnLoaded;
}
TDll=Classe(TObject)
privé
FPropriétaire : TDllManager ;
FModule : HMODULE ;
FFileName:Chaîne ;
Permis : booléen ;
procédureSetFileName(constValue:String);
functionGetLoaded:Booléen ;
procédureSetLoaded(constValue:Boolean);
procédureSetPermit(constValue:Boolean);
protégé
procédureDoDllLoaded;virtuel;
procédureDoBeforeDllUnLoaded;virtuel;
procédureDoDllUnLoaded;virtuel;
procédureDoFileNameChange;virtuel;
procédureDoPermitChange;virtuel;
publique
constructeurCréer;virtuel;
destructeurDestroy;remplacer;
functionGetProcAddress(constOrder:Longint):FARPROC;surcharge;
functionGetProcAddress(constProcName:String):FARPROC;surcharge;
propertyFileName:StringreadFFileNamewriteSetFileName ;
propertyLoaded:BooleanreadGetLoadedwriteSetLoaded ;
propertyOwner : TDllManagerreadFOwner ;
propertyPermit:BooleanreadFPermitwriteSetPermit ;
fin;
mise en œuvre
{TDll}
constructeurTDll.Create ;
commencer
FPropriétaire :=nil ;
FFileName :=´´ ;
FModule :=0 ;
FPermit :=Vrai ;
fin;
destructorTDll.Destroy;
var
Gestionnaire : TDllManager ;
commencer
Chargé :=Faux ;
ifFOwner<>nilthen
commencer
//在拥有者中删除自身
Gestionnaire : = FPropriétaire ;
//未防止在TDllManager中重复删除,因此需要将
//FOwner设置为nil;<--此段代码和TDllManager.Notify需要配合
//才能确保正确。
FPropriétaire :=nil ;
Manager.Remove (Self);
fin;
hérité;
fin;
functionTDll.GetLoaded:Booléen ;
commencer
résultat :=FModule<>0 ;
fin;
functionTDll.GetProcAddress(constOrder:Longint):FARPROC;
commencer
siChargéalors
résultat : = Windows.GetProcAddress (FModule, Pointeur (Ordre))
autre
raiseEDllError.CreateFmt(´DoLoadbeforeGetProcAddressof%u´,[DWORD(Order)]);
fin;
functionTDll.GetProcAddress(constProcName:String):FARPROC;
commencer
siChargéalors
résultat :=Windows.GetProcAddress(FModule,PChar(ProcName))
autre
raiseEDllError.CreateFmt(´DoLoadbeforeGetProcAddressof%s´,[ProcName]);
fin;
procédureTDll.SetLoaded(constValue:Boolean);
commencer
ifLoaded<>Valeuralors
commencer
sinonValeuralors
commencer
Assert(FModule<>0);
DoBeforeDllUnLoaded ;
essayer
Bibliothèque gratuite (FModule);
FModule :=0 ;
sauf
Application.HandleException(Self);
fin;
DoDllUnLoaded ;
fin
autre
commencer
FModule:=LoadLibrary(PChar(FFileName));
essayer
Win32Check(FModule<>0);
DoDllChargé ;
sauf
UnE:Exceptiondo
commencer
siFModule<>0alors
commencer
Bibliothèque gratuite (FModule);
FModule :=0 ;
fin;
raiseEDllError.CreateFmt(´LoadLibraryError:%s´,[E.Message]);
fin;
fin;
fin;
fin;
fin;
procédureTDll.SetFileName(constValue:String);
commencer
siChargéalors
raiseEDllError.CreateFmt(´DoUnloadbeforeloadanotherModulenamed:%s´,
[Valeur]);
ifFFileName<>Valeuralors
commencer
FFileName:=Valeur ;
DoFileNameChange;
fin;
fin;
procédureTDll.DoFileNameChange ;
commencer
//don rien.
fin;
procédureTDll.DoDllLoaded ;
commencer
si Assigned (FOwner) et Assigned (FOwner.OnDllLoaded) alors
FOwner.OnDllLoaded(FOwner,Self);
fin;
procédureTDll.DoDllUnLoaded ;
commencer
//don rien.
fin;
procédureTDll.DoPermitChange ;
commencer
//don rien.
fin;
procédureTDll.SetPermit(constValue:Boolean);
commencer
ifFPermit<>Valeuralors
commencer
FPermit:=Valeur ;
DoPermitChange ;
fin;
fin;
procédureTDll.DoBeforeDllUnLoaded ;
commencer
si Assigned (FOwner) et Assigned (FOwner.OnDllBeforeUnLoaded) alors
FOwner.OnDllBeforeUnLoaded(FOwner,Self);
fin;
{TDllManager}
functionTDllManager.Add(constFileName:String):Integer;
var
Dll : TDll ;
commencer
résultat :=-1 ;
Verrouillage;
essayer
ifDllsByName[FileName]=nilthen
commencer
Dll:=FDllClass.Create;
Dll.FileName:=FileName;
résultat:=Ajouter(Dll);
fin
autre
résultat :=-1 ;
enfin
Ouvrir;
fin;
fin;
constructeurTDllManager.Create ;
commencer
FDllClass:=TDll;
InitializeCriticalSection(FLock);
fin;
destructeurTDllManager.Destroy ;
commencer
SupprimerCriticalSection(FLock);
hérité;
fin;
functionTDllManager.GetDlls(constIndex:Integer):TDll;
commencer
Verrouillage;
essayer
si (Index>=0) et (Index <= Count-1) alors
résultat:=Articles[Index]
autre
raiseEDllError.CreateFmt(´ErrorIndexofGetDlls,Value:%d,TotalCount:%d´,[Index,Count]);
enfin
Ouvrir;
fin;
fin;
functionTDllManager.GetDllsByName(constFileName:String):TDll;
var
I : Entier ;
commencer
Verrouillage;
essayer
I:=IndexOf(NomFichier);
si je> = 0 alors
résultat :=Dlls[I]
autre
résultat :=nul ;
enfin
Ouvrir;
fin;
fin;
functionTDllManager.IndexOf(constFileName:String):Integer;
var
I : Entier ;
commencer
résultat :=-1 ;
Verrouillage;
essayer
pourI:=0toCount-1do
ifCompareText(FileName,Dlls[I].FileName)=0then
commencer
résultat:=I;
casser;
fin;
enfin
Ouvrir;
fin;
fin;
procédureTDllManager.Lock ;
commencer
OutputDebugString(Pchar(´TRLockDM´+IntToStr(GetCurrentThreadId)+´:´+IntToStr(DWORD(Self))));
EnterCriticalSection(FLock);
OutputDebugString(Pchar(´LockedDM´+IntToStr(GetCurrentThreadId)+´:´+IntToStr(DWORD(Self))));
fin;
procédureTDllManager.Notify(Ptr:Pointer;Action:TListNotification);
commencer
ifAction=lnDeletedthen
commencer
//若TDll(Ptr).Owner et Self不同,则
//表明由TDll.Destroy触发;
ifTDll(Ptr).Owner=Selfthen
commencer
//防止FOwner设置为nil之后相关事件不能触发
TDll(Ptr).DoBeforeDllUnLoaded;
TDll(Ptr).FOwner:=nil;
TDll(Ptr).Gratuit ;
fin;
fin
autre
ifAction=lnAddedthen
TDll(Ptr).FOwner:=Self;
hérité;
fin;
functionTDllManager.Remove(constFileName:String):Integer;
var
I : Entier ;
commencer
résultat :=-1 ;
Verrouillage;
essayer
I:=IndexOf(NomFichier);
si je> = 0 alors
résultat :=Supprimer(Dlls[I])
autre
résultat :=-1 ;
enfin
Ouvrir;
fin;
fin;
procédureTDllManager.UnLock ;
commencer
LeaveCriticalSection(FLock);
OutputDebugString(Pchar(´UnLockDM´+IntToStr(GetCurrentThreadId)+´:´+IntToStr(DWORD(Self))));
fin;
fin.