Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DLL Dynamisch Laden (https://www.delphipraxis.net/151302-dll-dynamisch-laden.html)

Ookami 11. Mai 2010 22:03


DLL Dynamisch Laden
 
Hallo zusammen,

ich weiß, dass dieses Thema schon oft diskutiert wurde. Habe selbst auch schon einige hilfreiche Tutorials dazu durchgeblättert.
Aber zum Funktionieren bringe ich das nicht. Statisch funktioniert, aber eben nicht dynamisch und jetzt wollte ich einfach einen Tip von euch.
Liegt's vielleicht an der Delphi Version? Hier Delphi 2009.

ich habe zunächst einfach ein Kapitel abgetippt zum Testen:


Die DLL
Delphi-Quellcode:
library Rechne;

uses
  SysUtils,
  Classes;

{$R *.res}

Function addiere (Value1, Value2 : Integer) : Integer; stdCall;
Begin
     Result := Value1 + Value2;
End;

Exports
       addiere;

begin
end.

Die Unit:
Delphi-Quellcode:
unit DLLUnit;

interface

Uses Windows;


Function addiere (Value1, Value2 : Integer) : Integer; stdCall;

implementation

Function addiere (Value1, Value2 : Integer) : Integer; stdCall; external 'rechne.DLL';

end.
Soweit hat man's schon oft gesehen, funktioniert auch, aber eben statisch!

Nun Dynamisch:
Delphi-Quellcode:
unit DLLUnit2;

interface

Uses Windows;


Type TAddition = Function (Value1, Value2 : Integer) : Integer;
Function addieren (Value1, Value2 : Integer) : Integer;

implementation


Function addieren (Value1, Value2 : Integer) : Integer;
Var     Addition : TAddition;
         Handle  : THandle;
Begin
     Handle := LoadLibrary('Rechne.DLL');
     if Handle <> 0 then
     Try
        @Addition := GetProcAddress(Handle, 'addiere');
        if @Addition <> nil then
        begin
             Result := Addition(Value1, Value2);
        end;
     Finally
          FreeLibrary(Handle);
     end;
End;

end.
Und hier hakt es bei der Result-Zeile.
Wie gesagt, nachdem das Beispiel abgetippt ist und so in zumindest ähnlicher Form in vielen verschiedenen Tut's oder Foren diskutiert wurde, eben die Frage, warum funktioniert es bei mir nicht?
Was habe ich nicht beachtet, was nicht richtig verstanden.

Ich danke euch vorab schon mal für eure Mühe
Gruß Wolfgang

BUG 11. Mai 2010 22:12

Re: DLL Dynamisch Laden
 
Delphi-Quellcode:
Exports
       addiere name 'addiere';
Warum das beim statischen Laden so klappt, ist mir ein Rätsel.

himitsu 11. Mai 2010 22:39

Re: DLL Dynamisch Laden
 
@BUG: In Delphi wird standardmäßig der Name der Prozedur verwendet, wenn nicht explizit ein Export-Name angegeben ist.



Code:
Function addiere (Value1, Value2 : Integer) : Integer; [color=#ff0000][b]stdCall;[/b][/color]
...

Exports
       addiere;
Code:
Function addiere (Value1, Value2 : Integer) : Integer; [color=#ff0000][b]stdCall;[/b][/color]
  external 'rechne.DLL';
Code:
Type TAddition = Function (Value1, Value2 : Integer) : Integer;
Fällt dir was auf?

PS: Wie die "unabhängige" Funktion Addition in der DLLUnit2 deklariert ist, ist egal, aber die Signatur des Prozudurzeigers muß schon zum Export passen.

PSS: in Delphi ist bei einer Zuweisung kein @ notwendig
Delphi-Quellcode:
Addition := GetProcAddress(Handle, 'addiere');
if Assigned(Addition) then
und das Result ist nicht initialisiert, wenn die DLL oder die Funktion nicht geladen/gefunden werden kann,
aber dieses müßte der Compiler eigentlich auch bemängeln. (Compiler-Meldung)

BUG 11. Mai 2010 22:53

Re: DLL Dynamisch Laden
 
Zitat:

Zitat von himitsu
@BUG: In Delphi wird standardmäßig der Name der Prozedur verwendet, wenn nicht explizit ein Export-Name angegeben ist.

Wieder was gelernt, was sogar massiv Schreibarbeit (+Tippfehler) sparen kann :mrgreen:

himitsu 11. Mai 2010 23:12

Re: DLL Dynamisch Laden
 
Man kann sogar ganze Funktions/Prozedur/Methoden-Signaturen einsparen
und bräuchte sie quasi nur im Interface zu erwähnen (außer bei überladenen Prozeduren, denn irgendwie muß Delphi ja unterscheiden können wer was ist :stupid: ).
Aber wenn man sie dennoch in der Implementation angibt, dann meckert Delphi wenigstens bei Unterschieden/Fehlern.
Delphi-Quellcode:
interface

Function addieren (Value1, Value2 : Integer) : Integer;

implementation

Function addieren;
Begin
  ...

Ookami 11. Mai 2010 23:27

Re: DLL Dynamisch Laden
 
Danke, Danke,

es funktioniert.
Manchmal ist man einfach mit Blindheit geschlagen. Dann tut es gut wenn man einem in Farbe die Augen öffnet.
Auch die anderen beiden Zusätze sind nicht nur OK, sondern Super.

Ihr habt mir sehr weitergeholfen
Gruß Wolfgang

Ookami 12. Mai 2010 00:07

Re: DLL Dynamisch Laden
 
Inspector Columbo sagte immer "Äh, eine Frage habe ich noch". Die meine mag ja nun etwas dumm erscheinen, aber ich denke, mancher hat sich diese auch schon gestellt.

Eine DLL wird ja, oftmals von mehreren Programmen quasi gleichzeitig benutzt. In meinem Fall sollte dies letztlich so sein.
Wenn ich z.B. in einer DLL nach deren Aufruf eine Liste aufbaue, so sind diese Daten ja zunächst im Speicher abgelegt.
Wenn ich später mit einem andern Programm dieselbe DLL aufrufe und an den Dateninhalt von exakt dieser Liste zugreifen möchte, geht das dann überhaupt?
Oder ist es so, dass dann die DLL für jedes Programm eine neue Liste anlegen müsste?

PS: Wer's nicht wusste, mit dem Beispiel von Himitsu, kann man in einer DLL auch eine andere DLL dynamisch laden.

schlecki 12. Mai 2010 07:57

Re: DLL Dynamisch Laden
 
Zitat:

Zitat von Ookami
Eine DLL wird ja, oftmals von mehreren Programmen quasi gleichzeitig benutzt. In meinem Fall sollte dies letztlich so sein.
Wenn ich z.B. in einer DLL nach deren Aufruf eine Liste aufbaue, so sind diese Daten ja zunächst im Speicher abgelegt.
Wenn ich später mit einem andern Programm dieselbe DLL aufrufe und an den Dateninhalt von exakt dieser Liste zugreifen möchte, geht das dann überhaupt?
Oder ist es so, dass dann die DLL für jedes Programm eine neue Liste anlegen müsste?

Jedes Programm wird deine DLL in seinen eigenen Adressraum laden => also muss auch jede Programm-DLL-Kombination die Liste selbst aufbauen. Man könnte das natürlich durch eine IPC innerhalb der DLL lösen (z.B. Memory Mapped Files). Oder du musst einen Out-of-Process-Server schreiben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:04 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