|
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.314 Beiträge Delphi 12 Athens |
#1
Delphi-Version: XE2
Verwendet dieses denn schon jemand ausgiebig?
Ich hab es grade so für mich (wieder)gefunden und will es demnächst einsetzen. Im Prinzip ist es eine wunderschöne Sache (vorallem man man Dieses auch noch komplett nutzt). Statisches Laden ist ja nicht immer möglich/erwünscht.
Delphi-Quellcode:
;
procedure MyProc(...);
... procedure MyProc(...); external 'My.dll'; external 'My.dll' name 'MyProc'; Und dynamisches Laden sieht häßlich aus.
Delphi-Quellcode:
Jetzt könnte man noch anfangen und Wrapper-Prozeduren drumrumpacken, damit es nach außen wieder ein "schöner" Prozeduraufruf wird
var MyProc = procedure(...);
// und dann irgendwo ein LoadLibrary und GetProcAddress und vorallem damit niemand "ausversehn" diese Variable überschreibt. Sooooooo, im Prinzip reicht es so schon aus: (LoadLibrary+GetProcAddress)
Delphi-Quellcode:
Schon wird die DLL erst beim ersten Aufruf der Funktion geladen.
function MyFunction(...): PChar;
function MyFunction(...): PChar; external 'my.dll' name 'MyFunction' delayed; Und nun nur noch das Endladen (FreeLibrary):
Delphi-Quellcode:
Um das jetzt noch ein bissl OOPiger hinzubekommen, hab ich das Ganze in einem Record gekapselt, wo der erste Parameter der Record selber ist.
UnloadDelayLoadedDLL('my.dll');
// Hier bitte ganz genau die Dokumentation (MSDN) durchlesen, da es ein/zwei Dinge zu beachten gibt. Man könnte aber auch statische Klassen-Prozeduren in (leeren) Records oder (abstrakten) Klassen nutzen.
Delphi-Quellcode:
procedure Test(Sender: TObject);
var F: TTestFunc; begin F.Time := Now; ShowMessage(F.ToTime); F := Now; ShowMessage(F.ToDate + ' ' + F.ToTime); F.Unload; end;
Delphi-Quellcode:
Im Anhang ist uch noch eine weitere "Klasse" (TDelayedLoadLibrary) drin, welche als Hook für die DLI-PI diehnt.
type
TTestFunc = record public const TheDLL = 'DelayedLoadDLL.dll'; public Time: TDateTime; function ToTime: PChar; // die beiden Funktionen in einem Record verpackt function ToDate: PChar; // function DateToStr(Time: PDataTime): PWideChar; class procedure Unload; static; class operator Implicit(const Rec: TDateTime): TTestFunc; class operator Implicit(const Rec: TTestFunc): TDateTime; end; class operator TTestFunc.Implicit(const Rec: TDateTime): TTestFunc; begin Result.Time := Rec; end; class operator TTestFunc.Implicit(const Rec: TTestFunc): TDateTime; begin Result := Rec.Time; end; function TTestFunc.ToDate: PChar; external TTestFunc.TheDLL name 'DateToStr' delayed; function TTestFunc.ToTime: PChar; external TTestFunc.TheDLL name 'TimeToStr' delayed; class procedure TTestFunc.Unload; type DLIUProc = function(szDll: PAnsiChar): LongBool; stdcall; begin if not DLIUProc(UnloadDelayLoadedDLLPtr)(TheDLL) then OutputDebugString('DLL was not unloaded'); end; Denn bei der originalen API kann man sich nur einmal registrieren (wie z.B. bei den alten Application.OnMessage) und diese Klasse ist nun mein "TApplicationEvents". ![]() (ohne würde es schwerer das Event zu nutzen, wenn man dieses mehrfach im Programm bräuchte, vorallem wenn dann in irgendeiner "Fremdkomponente" sich jemand zwar registriert, aber den Vorgänger vergisst aufzurufen ![]() PS: XE3 fehlt immernoch, aber ich gleub das gibt's auch schon in weilchen, also egal, aber irgendwas muß man ja auswählen, damit kein D5 dasteht ![]() [edit] bevor ich's wieder vergesse ... hier noch eine Debugausgabe zum Code in der DelayedLoadProcU.pas : (ein bissl aufgesplittet nach Funktionen und mit Positionsmarken versehn)
Code:
Prozess DelayedLoad.exe (4568)
Thread-Start: Thread-ID: 8668. Prozessstart: ...\DelayedLoad.exe. Basisadresse: $00400000. Modul laden: DelayedLoad.exe. Enthält Debug-Infos. Basisadresse: $00400000. Modul laden: ntdll.dll. Ohne Debug-Infos. Basisadresse: $77020000. Modul laden: KERNEL32.dll. Ohne Debug-Infos. Basisadresse: $74990000. Modul laden: KERNELBASE.dll. Ohne Debug-Infos. Basisadresse: $76710000. Modul laden: OLEAUT32.dll. Ohne Debug-Infos. Basisadresse: $74B40000. Modul laden: ole32.dll. Ohne Debug-Infos. Basisadresse: $765B0000. Modul laden: msvcrt.dll. Ohne Debug-Infos. Basisadresse: $74F80000. Modul laden: GDI32.dll. Ohne Debug-Infos. Basisadresse: $76200000. Modul laden: USER32.dll. Ohne Debug-Infos. Basisadresse: $762F0000. Modul laden: ADVAPI32.dll. Ohne Debug-Infos. Basisadresse: $763F0000. Modul laden: SECHOST.dll. Ohne Debug-Infos. Basisadresse: $74790000. Modul laden: RPCRT4.dll. Ohne Debug-Infos. Basisadresse: $74BD0000. Modul laden: SspiCli.dll. Ohne Debug-Infos. Basisadresse: $74700000. Modul laden: CRYPTBASE.dll. Ohne Debug-Infos. Basisadresse: $746F0000. Modul laden: LPK.dll. Ohne Debug-Infos. Basisadresse: $74980000. Modul laden: USP10.dll. Ohne Debug-Infos. Basisadresse: $75E90000. Modul laden: VERSION.dll. Ohne Debug-Infos. Basisadresse: $721F0000. Modul laden: COMCTL32.dll. Ohne Debug-Infos. Basisadresse: $73570000. Modul laden: SHLWAPI.dll. Ohne Debug-Infos. Basisadresse: $76290000. Modul laden: SHELL32.dll. Ohne Debug-Infos. Basisadresse: $751F0000. Modul laden: WINSPOOL.DRV. Ohne Debug-Infos. Basisadresse: $737F0000. Modul laden: IMM32.dll. Ohne Debug-Infos. Basisadresse: $75190000. Modul laden: MSCTF.dll. Ohne Debug-Infos. Basisadresse: $75F70000. Modul laden: UxTheme.dll. Ohne Debug-Infos. Basisadresse: $73950000. Modul laden: dwmapi.dll. Ohne Debug-Infos. Basisadresse: $74650000. Modul laden: WTSAPI32.dll. Ohne Debug-Infos. Basisadresse: $741F0000. Modul laden: WINSTA.dll. Ohne Debug-Infos. Basisadresse: $73C60000. Thread-Start: Thread-ID: 4148. Thread-Start: Thread-ID: 13156. 1: Debug-Ausgabe: ProcAddr: $005A83F8 2: Debug-Ausgabe: dliStartProcessing: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: dliNotePreLoadLibrary: DelayedLoadDLL.dll TimeToStr Modul laden: DelayedLoadDLL.dll. Ohne Debug-Infos. Basisadresse: $04B60000. Debug-Ausgabe: Load DLL: DelayedLoadDLL.dll Debug-Ausgabe: dliNotePreGetProcAddress: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: dliNoteEndProcessing: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: 06:06:07.165 3: Debug-Ausgabe: ProcAddr: $005A83F8 <> $04C2D568 4: Debug-Ausgabe: Unload DLL: DelayedLoadDLL.dll Modul entladen: DelayedLoadDLL.dll. 5: Debug-Ausgabe: ProcAddr: $005A83F8 = $005A83F8 6: Debug-Ausgabe: dliStartProcessing: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: dliNotePreLoadLibrary: DelayedLoadDLL.dll TimeToStr Modul laden: DelayedLoadDLL.dll. Ohne Debug-Infos. Basisadresse: $04B60000. Debug-Ausgabe: Load DLL: DelayedLoadDLL.dll Debug-Ausgabe: dliNotePreGetProcAddress: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: dliNoteEndProcessing: DelayedLoadDLL.dll TimeToStr Debug-Ausgabe: 06:07:07.178 7: Debug-Ausgabe: dliStartProcessing: DelayedLoadDLL.dll DateToStr Debug-Ausgabe: dliNotePreGetProcAddress: DelayedLoadDLL.dll DateToStr Debug-Ausgabe: dliNoteEndProcessing: DelayedLoadDLL.dll DateToStr Debug-Ausgabe: 2012-11-15 8: Debug-Ausgabe: ProcAddr: $005A83F8 <> $04C2D568 = $04C2D568 Modul laden: ole32.dll. Ohne Debug-Infos. Basisadresse: $05130000. Modul entladen: ole32.dll. Debug-Ausgabe: dliStartProcessing: DWMAPI.DLL DwmIsCompositionEnabled Debug-Ausgabe: dliNotePreLoadLibrary: DWMAPI.DLL DwmIsCompositionEnabled Debug-Ausgabe: dliNotePreGetProcAddress: DWMAPI.DLL DwmIsCompositionEnabled Debug-Ausgabe: dliNoteEndProcessing: DWMAPI.DLL DwmIsCompositionEnabled Debug-Ausgabe: dliStartProcessing: DWMAPI.DLL DwmExtendFrameIntoClientArea Debug-Ausgabe: dliNotePreGetProcAddress: DWMAPI.DLL DwmExtendFrameIntoClientArea Debug-Ausgabe: dliNoteEndProcessing: DWMAPI.DLL DwmExtendFrameIntoClientArea (wie man sieht, nutzt auch Emba selbst diese Technik) Programm und Fenster sind fertig geladen (den Rest hab'sch weggelassen)
Ein Therapeut entspricht 1024 Gigapeut.
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |