Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DLL Funktionen dynamisch laden (https://www.delphipraxis.net/112456-dll-funktionen-dynamisch-laden.html)

hedie 21. Apr 2008 18:48


DLL Funktionen dynamisch laden
 
Hallo

Ich möchte DLL's sowie deren Funktionen Dynamisch laden.

Das bedeutet, das das programm zu beginn die Funktionen einer DLL Nicht kennt
sondern diese als string in der form von: function rechnen(zahl:integer);stdcall;
vorliegen.

Das Programm soll dan automatisch die entsprechenden Funktionen und Proceduren nutzen können.

Wie kann man so etwas realisieren?

Danke schonmal

Apollonius 21. Apr 2008 18:52

Re: DLL Funktionen dynamisch laden
 
Du brauchst nur den Funktionsnamen (Aufrufkonvention, Parameterzahl etc. kannst du nicht überprüfen; falls sie nicht stimmen, kriegst du, wenn du Glück hast, eine Zugriffsverletzung). Die DLL lädst du mit LoadLibrary und verwendest den Rückgabewert für GetProcAddress, welches den Funktionszeiger zurückgibt. Dazu gibt es auch ziemlich viele Tutorials.

hedie 21. Apr 2008 18:53

Re: DLL Funktionen dynamisch laden
 
hmmm

könntest du ein kleines beispiel posten?
Irgendwie blick ich da noch nicht 100% durch

Ghostwalker 21. Apr 2008 18:55

Re: DLL Funktionen dynamisch laden
 
Delphi-Quellcode:
   var MeineFunc : Function (param:pchar):boolean;
   var dllhandle : THandle;

   Function Load_DLL (const dllfilename:string) :boolean;
   begin
     dllhandle := LoadLibrary(pchar(dllfilename));
    if (dllhandle <> 0) then
       MeineFunc := GetProcAdress(dllhandle,pchar('MeineFunction'));
   end;
Mit LoadLibrary lädst du die DLL selbst. Das gibt dir ein Handle auf die DLL zurück.
Mit GetProcAdress holst du die Adresse der Funktion. Anschließend kannst du
ganz normal auf MeineFunc zugreifen.

Wenn alles getant ist und die DLL nicht mehr gebraucht wird, mit FreeLibrary wieder freigeben :)

hedie 21. Apr 2008 18:57

Re: DLL Funktionen dynamisch laden
 
Was wenn ich mehr als eine Funktion habe die genaue anzahl jedoch nicht von beginn an bekannt ist?

Irgendwie 100 mal ne variable schreiben lohnt sich ja nicht oder?

sirius 21. Apr 2008 19:17

Re: DLL Funktionen dynamisch laden
 
Du kannst GetProcAddress zu beleibigen Zeitpunkten aufrufen. Du kannst auch in die DLL schauen, was für Funktionen da zugänglich sind (allerdings musst du da selber den PE-HEader und die Export-Tble auswerten; eine Funktion gibt es dazu nicht).
Was brauchst du noch?

OldGrumpy 22. Apr 2008 09:08

Re: DLL Funktionen dynamisch laden
 
Ich vermute das soll auf ein Plugin-System hinauslaufen, davon wurden hier ja auch schon einige vorgestellt. Einfach mal die Boardsuche mit "plugin" und "system" füttern oder sowas :)

hedie 22. Apr 2008 10:16

Re: DLL Funktionen dynamisch laden
 
Ja du hast recht :D

Aber ich gebe einfach vor das jede Funktion einer DLL
einen TMemoryStream zurück geben muss, damit kann
man bei meinem vorhaben schon genug anfangen :D

Aber trozdem danke!

Luckie 22. Apr 2008 10:46

Re: DLL Funktionen dynamisch laden
 
Das dürfte aber nicht mit dem Standardmemorymanager gehen.

QuickAndDirty 22. Apr 2008 10:58

Re: DLL Funktionen dynamisch laden
 
dann must du eine BPL machen!!!
Oder du must einfach einen Zeiger auf einen Record mit den werten Size und Buffer
zurrückgeben.

hedie 22. Apr 2008 11:24

Re: DLL Funktionen dynamisch laden
 
Habe solch eine Funktion in der DLL

Delphi-Quellcode:
function hwfunc():TMemoryStream;stdcall;
var
vfile:TStringlist;
begin
result := TMemoryStream.Create;
vfile := tstringlist.Create;
vfile.Add('Test :D');
vfile.SaveToStream(result);
vfile.Free;
result.Position := 0;
end;
Aufgerufen wird sie folgendermasen:

Delphi-Quellcode:
DynMain.ContentStream := dynfunc(nil);
DynMain.WriteContent;
dynfunc(nil).Free;
Und es funktioniert alles einwandfrei :D

SirThornberry 22. Apr 2008 11:53

Re: DLL Funktionen dynamisch laden
 
irgendwas passt da aber nicht zusammen.
Du rufst eine Funktion auf und gibst einen parameter mit obwohl die Funktion keinen Hat.
Dann erstellst du in der Funktion eine Objectinstanz.
Und anschließend rufst du die Funktion nochmal auf, es wird wieder eine Objectinstanz erstellt welche aber sofort wieder frei gegeben wird. Die erste wird scheinbar nie frei gegeben und der zweite Aufruf der Funktion ist völlig sinnlos.

hedie 22. Apr 2008 11:59

Re: DLL Funktionen dynamisch laden
 
Hmmm.... ich hab das nun noch ein wenig modifiziert...

Neie DLL Funktion

Delphi-Quellcode:
function hwfunc(ReqInfo:TIdHTTPRequestInfo;ResInfo:TIdHTTPResponseInfo):TMemoryStream;stdcall;
var
vfile:TStringlist;
begin
result := TMemoryStream.Create;
vfile := tstringlist.Create;
vfile.Add('Test hahah _:D');
vfile.SaveToStream(result);
vfile.Free;
result.Position := 0;
ResInfo.ContentStream := result;
ResInfo.WriteContent;
result.Free;
end;
Das es ein paar unschönheiten hat weiss ich.... is erst experimentell :D

Der neue aufruf

Delphi-Quellcode:
dynfunc(ARequestInfo,AResponseInfo);
Auch dies funktioniert wieder jedoch
meldet er ab und zu Ungültige Zeigeroperation

Jedoch bricht das programm nicht ab sondern die Meldung wird
zum text Test haha _:D Hinzugefügt...

SirThornberry 22. Apr 2008 12:02

Re: DLL Funktionen dynamisch laden
 
die ungültige zeigeroperation kommt daher das du speicher außerhalb der dll frei gibst welcher aber in der dll angefordert wurde. Die DLL und das Hauptprogramm haben getrennte Speichermanager (sofern nicht ShareMem etc. verwendet wird). Du kannst also nicht einfach den Speicher eines anderen Memorymanagers frei geben.

Prinzipiell sollte man (guter Stil) Daten dort frei geben wo sie auch angefordert werden (Ebene sowie Modul).

hedie 22. Apr 2008 12:04

Re: DLL Funktionen dynamisch laden
 
Ok hmmm

Und das die meldung nicht immer kommt is normal?

Und wie kann ich das nun korrekt lösen?

SirThornberry 22. Apr 2008 12:08

Re: DLL Funktionen dynamisch laden
 
das die meldung nicht immer kommt ist auch normal. Lösung:
Delphi-Quellcode:
//dll
procedure FreeObj(Obj: TObject); stdcall;
begin
  Obj.Free;
end;

hedie 22. Apr 2008 12:09

Re: DLL Funktionen dynamisch laden
 
Und diese Procedure soll ich wann aufrufen?

Ghostwalker 22. Apr 2008 12:14

Re: DLL Funktionen dynamisch laden
 
Delphi-Quellcode:
function hwfunc(ReqInfo:TIdHTTPRequestInfo;ResInfo:TIdHTTPResponseInfo):TMemoryStream;stdcall;
var
vfile:TStringlist;
begin
result := TMemoryStream.Create;
vfile := tstringlist.Create;
vfile.Add('Test hahah _:D');
vfile.SaveToStream(result);
vfile.Free;
result.Position := 0;
ResInfo.ContentStream := result;
ResInfo.WriteContent;
result.Free; / <-- Soll das da wirklich sein ???????????
end;
Ich denke nicht. Schließlich willst du außerhalb der DLL auf das Ergebnis der Funktion zu greifen.


Sauber wäre:

Delphi-Quellcode:
Procedure hwfunc(Var Result:TMemoryStream;ReqInfo:TIdHTTPRequestInfo;ResInfo:TIdHTTPResponseInfo);stdcall;
var
vfile:TStringlist;
begin
vfile := tstringlist.Create;
vfile.Add('Test hahah _:D');
vfile.SaveToStream(result);
vfile.Free;
result.Position := 0;
ResInfo.ContentStream := result;
ResInfo.WriteContent;
end;
Wobei Result außerhalb der DLL allociert und freigegeben werden sollte. :)

hedie 22. Apr 2008 12:17

Re: DLL Funktionen dynamisch laden
 
also muss ich das create in der anwendung machen wo ich die DLL Lade?

sirius 22. Apr 2008 12:33

Re: DLL Funktionen dynamisch laden
 
Zitat:

Zitat von hedie
also muss ich das create in der anwendung machen wo ich die DLL Lade?

Wenn du den Memorystream auch in der Anwendung brauchst: Ja

hedie 22. Apr 2008 12:35

Re: DLL Funktionen dynamisch laden
 
Ja das Free soll wirklich sein,
da die Variablen ResInfo und ReqInfo diese von der ladenden EXE sind
also es soll mit den Variablen aus der EXE Gearbeitet werden.

In etwa so

Delphi-Quellcode:
function blabla(var1:string;var2:string); //Funktion in der exe als beispiel
begin

beispielddl(var1,var2);
showmessage(var1);

end;

///////////////////DLL//////////////////

function beispieldll(variable1:string;variable2:string);stdcall;
begin
variable1 := 'Neuer Text1';
variable2 := 'Neuer Text2';
end;
Wenn bei diesem Beispiel nun die MessageBox kommt, sollte darin
der Text: Neuer Text1 sichtbar sein.

Das habe ich jetzt so gelöst (mit anderen variable typen) und es hat geklappt
bis auf die meldung ungültige zeiger operation

sirius 23. Apr 2008 11:36

Re: DLL Funktionen dynamisch laden
 
Und wie hast du es wirklich gemacht?
Du kannst ja keine Strings über DLL Grenzen verschieben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz