unituntDllManager;
อินเตอร์เฟซ
การใช้งาน
Windows, คลาส, SysUtils, แบบฟอร์ม;
พิมพ์
EDllError=คลาส(ข้อยกเว้น);
TDllClass=ClassofTDll;
TDll=คลาส;
TDllEvent=ขั้นตอน(ผู้ส่ง:TObject;ADll:TDll)ของObject;
{TDllManager
o 提供对Dll ของ管理功能;
oAdd时自动创建TDll对象,但不尝试装载;
oDelete การลบ TDll ออกไป
-
TDllManager=คลาส(TLList)
ส่วนตัว
ฝูง: TRTLCriticalSection;
FDllClass:TDllClass;
FOnDllLoad:TDllEvent;
FOnDllBeforeUnLoaded:TDllEvent;
functionGetDlls(constIndex:จำนวนเต็ม):TDll;
functionGetDllsByName(constFileName:String):TDll;
ได้รับการคุ้มครอง
ProcedureNotify (Ptr: ตัวชี้; การกระทำ: TListNotification); แทนที่;
สาธารณะ
ตัวสร้างสร้าง;
destructorDestroy; แทนที่;
functionAdd(constFileName:String):จำนวนเต็ม;โอเวอร์โหลด;
functionIndexOf(constFileName:String): จำนวนเต็ม; โอเวอร์โหลด;
functionRemove(constFileName:String):จำนวนเต็ม;โอเวอร์โหลด;
ขั้นตอนล็อค;
ขั้นตอน UnLock;
คุณสมบัติDllClass:TDllClassreadFDllClasswriteFDllClass;
propertyDlls[constIndex:Integer]:TDllreadGetDlls;ค่าเริ่มต้น;
propertyDllsByName[constFileName:String]:TDllreadGetDllsByName;
คุณสมบัติ OnDllLoaded: TDllEventreadFOnDllLoadwriteFOnDllLoad;
คุณสมบัติ OnDllBeforeUnLoaded:TDllEventreadFOnDllBeforeUnLoadedwriteFOnDllBeforeUnLoaded;
จบ;
{TDll
หรือไปที่ Dll,Windows.HModule
o销毁时自动在Owner中删除自身;
o子类可通过覆盖แทนที่DoDllLoaded, 以及DoDllUnLoaded进行功能扩ส่วนขยาย;
-
TDll=คลาส(TObject)
ส่วนตัว
เจ้าของ: TDllManager;
Fโมดูล:HMODULE;
FFileName:สตริง;
FPermit:บูลีน;
ProcedureSetFileName(constValue:สตริง);
functionGetLoaded:บูลีน;
ProcedureSetLoaded(constValue:บูลีน);
ProcedureSetPermit(constValue:บูลีน);
ได้รับการคุ้มครอง
ProcedureDoDllLoaded;เสมือน;
ขั้นตอนDoBeforeDllUnLoaded;เสมือน;
ขั้นตอน DoDllUnLoaded; เสมือน;
ขั้นตอนDoFileNameChange;เสมือน;
ขั้นตอน DoPermitChange; เสมือน;
สาธารณะ
ตัวสร้างสร้าง;เสมือน;
destructorDestroy; แทนที่;
functionGetProcAddress (constOrder: Longint): FARPROC; โอเวอร์โหลด;
functionGetProcAddress (constProcName:String): FARPROC โอเวอร์โหลด;
คุณสมบัติFileName:StringreadFFileNamewriteSetFileName;
คุณสมบัติLoaded:BooleanreadGetLoadedwriteSetLoaded;
เจ้าของทรัพย์สิน: TDllManagerreadFowner;
คุณสมบัติ Permit: BooleanreadFPermitwriteSetPermit;
จบ;
การดำเนินการ
{TDll}
ตัวสร้างTDll.Create;
เริ่ม
เจ้าของ:=ไม่มี;
FFileName:=``;
เอฟโมดูล:=0;
FPermit:=จริง;
จบ;
destructorTDll.ทำลาย;
var
ผู้จัดการ:TDllManager;
เริ่ม
โหลดแล้ว:=เท็จ;
ifFowner<>ไม่มีเลย
เริ่ม
//在拥有者中删除自身
ผู้จัดการ:=เจ้าของ;
//未防止在TDllManager中重复删除,因此需要将
//Fowner设置为nil;<--此段代码和TDllManager.Notify需要配合
//才能确保正确。
เจ้าของ:=ไม่มี;
Manager.Remove(ตนเอง);
จบ;
สืบทอด;
จบ;
functionTDll.GetLoaded:บูลีน;
เริ่ม
ผลลัพธ์:=FModule<>0;
จบ;
functionTDll.GetProcAddress (constOrder: Longint): FARPROC;
เริ่ม
ถ้าโหลดแล้ว
ผลลัพธ์:=Windows.GetProcAddress(FModule,Pointer(Order))
อื่น
RaiseEDllError.CreateFmt('DoLoadbeforeGetProcAddressof%u',[DWORD(คำสั่งซื้อ)]);
จบ;
functionTDll.GetProcAddress (constProcName:String): FARPROC;
เริ่ม
ถ้าโหลดแล้ว
ผลลัพธ์: = Windows.GetProcAddress (FModule, PChar (ProcName))
อื่น
RaiseEDllError.CreateFmt('DoLoadbeforeGetProcAddressof%s',[ProcName]);
จบ;
ขั้นตอน TDll.SetLoaded (constValue: บูลีน);
เริ่ม
ifLoaded<>ให้คุณค่าแล้ว
เริ่ม
ถ้าไม่มีคุณค่า
เริ่ม
ยืนยัน(FModule<>0);
ทำก่อน DllUnLoaded;
พยายาม
ห้องสมุดอิสระ(FModule);
เอฟโมดูล:=0;
ยกเว้น
Application.HandleException (ตนเอง);
จบ;
DoDllUnLoaded;
จบ
อื่น
เริ่ม
FModule:=LoadLibrary(PChar(FFileName));
พยายาม
Win32Check(FModule<>0);
DoDllLoaded;
ยกเว้น
หนึ่งE:ยกเว้นทำ
เริ่ม
ifFModule<>0แล้ว
เริ่ม
ห้องสมุดอิสระ(FModule);
เอฟโมดูล:=0;
จบ;
RaiseEDllError.CreateFmt('LoadLibraryError:%s',[E.Message]);
จบ;
จบ;
จบ;
จบ;
จบ;
ขั้นตอน TDll.SetFileName(constValue:String);
เริ่ม
ถ้าโหลดแล้ว
RaiseEDllError.CreateFmt('DoUnloadbeforeloadanotherModulenamed:%s',
[ค่า]);
ifFFileName<>ให้คุณค่าแล้ว
เริ่ม
FFileName:=ค่า;
ทำ FileNameChange;
จบ;
จบ;
ขั้นตอน TDll.DoFileNameChange;
เริ่ม
//ไม่ได้อะไรเลย.
จบ;
ขั้นตอน TDll.DoDllLoaded;
เริ่ม
ifAssigned(Fowner)และAssigned(Fowner.OnDllLoaded)แล้ว
Fowner.OnDllLoaded (เจ้าของตนเอง);
จบ;
ขั้นตอน TDll.DoDllUnLoaded;
เริ่ม
//ไม่ได้อะไรเลย.
จบ;
ขั้นตอน TDll.DoPermitChange;
เริ่ม
//ไม่ได้อะไรเลย.
จบ;
ขั้นตอน TDll.SetPermit (constValue:บูลีน);
เริ่ม
ifFPermit<>ให้คุณค่า
เริ่ม
FPermit:=ค่า;
ขออนุญาตเปลี่ยนแปลง;
จบ;
จบ;
ขั้นตอน TDll.DoBeforeDllUnLoaded;
เริ่ม
ifAssigned (Fowner) และ Assigned (Fowner.OnDllBeforeUnLoaded) แล้ว
Fowner.OnDllBeforeUnLoaded (เจ้าของตนเอง);
จบ;
{TDllManager}
functionTDllManager.Add(constFileName:String):จำนวนเต็ม;
var
Dll:TDll;
เริ่ม
ผลลัพธ์:=-1;
ล็อค;
พยายาม
ifDllsByName[ชื่อไฟล์]=ไม่มี
เริ่ม
Dll:=FDllClass.Create;
Dll.FileName:=ชื่อไฟล์;
ผลลัพธ์:=เพิ่ม(Dll);
จบ
อื่น
ผลลัพธ์:=-1;
ในที่สุด
ปลดล็อค;
จบ;
จบ;
ตัวสร้างTDllManager.Create;
เริ่ม
FDllClass:=TDll;
เตรียมใช้งาน CriticalSection (FLock);
จบ;
destructorTDllManager.ทำลาย;
เริ่ม
DeleteCriticalSection(FLock);
สืบทอด;
จบ;
functionTDllManager.GetDlls(constIndex:จำนวนเต็ม):TDll;
เริ่ม
ล็อค;
พยายาม
ถ้า(ดัชนี>=0)และ(ดัชนี<=Count-1)แล้ว
ผลลัพธ์:=รายการ[ดัชนี]
อื่น
RaiseEDllError.CreateFmt('ErrorIndexofGetDlls,Value:%d,TotalCount:%d',[ดัชนี,นับ]);
ในที่สุด
ปลดล็อค;
จบ;
จบ;
functionTDllManager.GetDllsByName(constFileName:String):TDll;
var
ฉัน:จำนวนเต็ม;
เริ่ม
ล็อค;
พยายาม
I:=IndexOf(ชื่อไฟล์);
ถ้าI>=0แล้ว
ผลลัพธ์:=ที่กำลัง[I]
อื่น
ผลลัพธ์:=ไม่มี;
ในที่สุด
ปลดล็อค;
จบ;
จบ;
functionTDllManager.IndexOf (constFileName:String): จำนวนเต็ม;
var
ฉัน:จำนวนเต็ม;
เริ่ม
ผลลัพธ์:=-1;
ล็อค;
พยายาม
สำหรับI:=0toCount-1do
ifCompareText(FileName,Dlls[I].FileName)=0แล้ว
เริ่ม
ผลลัพธ์:=ฉัน;
หยุดพัก;
จบ;
ในที่สุด
ปลดล็อค;
จบ;
จบ;
ขั้นตอน TDllManager.Lock;
เริ่ม
OutputDebugString(Pchar('TRLockDM'+IntToStr(GetCurrentThreadId)+':'+IntToStr(DWORD(ตนเอง))));
EnterCriticalSection(FLock);
OutputDebugString(Pchar('LockedDM'+IntToStr(GetCurrentThreadId)+':'+IntToStr(DWORD(ตนเอง))));
จบ;
ขั้นตอน TDllManager.Notify (Ptr: ตัวชี้; การกระทำ: TListNotification);
เริ่ม
ifAction=lnลบแล้ว
เริ่ม
//若TDll(Ptr).Owner和Self不同,则
//表明由TDll.Destroy触发;
ifTDll(Ptr).Owner=ตนเอง
เริ่ม
//防止Fowner设置为nil之后相关事件不能触发
TDll(Ptr).DoBeforeDllUnLoaded;
TDll(Ptr).Fowner:=ไม่มี;
TDll(Ptr) ฟรี;
จบ;
จบ
อื่น
ifAction=lnเพิ่มแล้ว
TDll(Ptr).Fowner:=ตนเอง;
สืบทอด;
จบ;
functionTDllManager.Remove(constFileName:String):จำนวนเต็ม;
var
ฉัน:จำนวนเต็ม;
เริ่ม
ผลลัพธ์:=-1;
ล็อค;
พยายาม
I:=IndexOf(ชื่อไฟล์);
ถ้าI>=0แล้ว
ผลลัพธ์:=ลบ(Dlls[I])
อื่น
ผลลัพธ์:=-1;
ในที่สุด
ปลดล็อค;
จบ;
จบ;
ขั้นตอน TDllManager.UnLock;
เริ่ม
ออกจาก CriticalSection (FLock);
OutputDebugString(Pchar('UnLockDM'+IntToStr(GetCurrentThreadId)+':'+IntToStr(DWORD(ตัวเอง))));
จบ;
จบ.