Einzelnen Beitrag anzeigen

Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.619 Beiträge
 
Delphi 12 Athens
 
#12

Re: Bedingt Prozedur aufrufen

  Alt 24. Jan 2008, 10:48
Zitat aus Ollis Tut:
Zitat:
Beispiel: Dynamischer Import von DLL-Funktionen
Der dynamische Import funktioniert, wie schon gesagt, über das Holen der Adresse der zu
importierenden Funktion durch den Aufrufer.
Zuallererst muß der Aufrufer aber auch die Syntax der Funktion bekannt gemacht bekommen. Auch
wenn ein Funktionsaufruf „untendrunter“ quasi nur ein Sprung an eine bestimmte Adresse ist, kann
man ja in seinem Programm nicht wild an irgendeine Adresse springen lassen – wie sollen da die
Parameter übergeben werden? Es muß also ein sogenannter Funktionsprototyp her. In C(++) sind
die Funktionsprototypen meist in einer Header-Datei19 aufgeführt. Dies ist auch der Grund warum
diese vorher nach Delphi (ObjectPascal) übersetzt werden müssen (siehe Appendix A). Ähnlich wie
in C(++) ist die Funktionsprototypen-Deklaration in Delphi auch nur eine normale Typendeklaration:
Delphi-Quellcode:
type
TFNOneFunction = function(param1, param2, param3: Cardinal): integer;
TFNOneFunction_CDECL = function(param1, param2, param3: Cardinal): integer;
cdecl;
TFNOneFunction_STDCALL = function(param1, param2, param3: Cardinal): integer;
stdcall;
TFN ist übrigens in Delphi eine offiziell anerkannte Notation20 für Funktionstypen.
Da wir die Typen deklariert haben, brauchen wir nun noch die entsprechenden Variablen:
Delphi-Quellcode:
var
OneFunction: TFNOneFunction = nil;
OneFunction_CDECL: TFNOneFunction_CDECL = nil;
OneFunction_STDCALL_: TFNOneFunction_STDCALL = nil;
Die Variablen müssen global deklariert sein um sie mit nil initialisieren zu können, denn Delphi
erlaubt das Vorinitialisieren von Variablen nur im globalen Kontext. Nun müssen wir uns in einer, ich
schlage vor getrennten Funktion, die Adressen oder sogenannten Eintrittspunkte der Funktionen
holen:
Delphi-Quellcode:
Procedure GetEntryPoints;
var
lib:THandle;
begin
lib := LoadLibrary(@szNameDLL[1]);
case lib = 0 of
TRUE:
begin
@OneFunction_CDECL := @whatifnoentry;
@OneFunction := @whatifnoentry;
@OneFunction_STDCALL_ := @whatifnoentry;
messagebox(0, @dll_notloaded[1], nil, 0);
end;
else
begin
@OneFunction := GetProcAddress(lib, @szNameOneFunction[1]);
if not Assigned(OneFunction) then @OneFunction := @whatifnoentry;
@OneFunction_CDECL := GetProcAddress(lib, @szNameOneFunction_CDECL[1]);
if not Assigned(OneFunction_CDECL) then @OneFunction_CDECL :=
@whatifnoentry;
@OneFunction_STDCALL_ := GetProcAddress(lib, @szNameOneFunction_STDCALL[1]);
if not Assigned(OneFunction_STDCALL_) then @OneFunction_STDCALL_ :=
@whatifnoentry;
end;
end;
Man kann das Handle durch einen Aufruf von FreeLibrary() freigeben. Dies wird aber auch von
Windows erledigt, wenn der Prozeß beendet wird.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat