Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dll zur Laufzeit verändern? (https://www.delphipraxis.net/32705-dll-zur-laufzeit-veraendern.html)

StanY 27. Okt 2004 14:25


Dll zur Laufzeit verändern?
 
Also: Ich 'arbeite' grade an einem kleinem IRC Bot. Soweit läuft alles auch ganz gut, mal abgesehen, dass er recht groß ist, da ich noch nicht non-vcl schreiben kann. Aber das ist erstmal egal.

Relevant ist, dass ich ihn nun DLL basiert erstellt habe. Der Bot läuft und greift bei jeder Msg, die ankommt, auf die DLL zu und überprüfr ob und wenn ja, was zu tun ist.

Nun hatte ich mir das eigentlich so vorgestellt, dass ich die DLL während der Laufzeit des Bots einfach austauschen kann, ohne, dass der Bot neu zum IRC connecten muss, was ja vorher noch der Fall war.
Gedacht, getan, nur leider kann ich die DLL nicht austauschen, 'da sie von einem anderen Programm benutzt wird'.

Wie kann ich das, was ich vor habe, realisieren?

Vielen Dank schonmal im Vorraus.

dizzy 27. Okt 2004 14:28

Re: Dll zur Laufzeit verändern?
 
Das Stichwort hier wäre "dynamisches Laden". So kannst du sie auch wieder, im Betrieb, entladen, austauschen und wieder anpappen. Dazu habe ich mal ein Tut auf www.delphi-treff.de oder auf www.delphi-source.de gesehen. (Einfach mal suchen ;))

Gruss,
Fabian

StanY 27. Okt 2004 14:29

Re: Dll zur Laufzeit verändern?
 
Mh danke. Habe mir das Tutorial dazu durchgelesen (schon gestern) aber dachte es wäre auch einfacher möglich^^. Dann mache ich mich mal daran, das nochmal zu tun \:.

Danke.

fiasko 27. Okt 2004 14:30

Re: Dll zur Laufzeit verändern?
 
Hallo,

Solange die DLL geöffnet ist, kannst du sie nicht ersetzen (geschweige denn würde der neue Code ausgeführt werden können).

Mach in deinem Bot eine Schnittstelle über die man sagen kann "entlade-die-dll", dann wird sie ersetzt und dann kommt ein neues Kommando "lade-die-dll". Die schnittstelle könnte einen named pipe sein oder er hört auf einem lokalen UDP-Socket - das ganze wird dann einfach mit nem Hilfsprogramm angesteuert.

Luckie 27. Okt 2004 14:31

Re: Dll zur Laufzeit verändern?
 
Warum ist alles, was man auf Anhieb nicht versteht gleich schwer und es wird nach einer "einfachheren" Möglichkeit gesucht? :gruebel: Da mus sman sich eben mal damit etwas auseinadersetzten.

StanY 27. Okt 2004 15:11

Re: Dll zur Laufzeit verändern?
 
Ich habe die DLL jetzt dynamisch eingebunden, aber sobald die Prozedur in der DLL ausgeführt wird, bekomme ich ein AccessViolation-Error

Die Prozedur LoadDll(DllName: String); wird inFrom1.Create aufgerufen.
Delphi-Quellcode:
procedure TfrmMain.LoadDll(DllName: String);
var
  Handle: THandle;
begin
  //Dll wird nun eingebunden
  Handle := LoadLibrary(PChar(DllName));
  if (Handle <> 0) then begin
    GetCommand := GetProcAddress(Handle,'GetCommand');
  end;
  FreeLibrary(Handle);
end;
GetCommand wird global deklariert und zwar als TGetCommand, welches so aussieht:
Delphi-Quellcode:
TGetCommand = procedure(CmdStr: String; SockId: Integer); stdcall;
Sobald ich GetCommand(); aufrufe, gibt es den Fehler. Folglich wird wohl etwas bei LoadDll nicht stimmen, aber was?

Btw.:
Die Dll sieht so aus:
Delphi-Quellcode:
library commdll;

uses
  SysUtils,
  Classes,
  Dialogs;

{$R *.res}

procedure GetCommand();
begin
  ShowMessage('yes');
end;

exports
  GetCommand;

begin
end.

Dax 27. Okt 2004 15:12

Re: Dll zur Laufzeit verändern?
 
So müsste es gehen:
Delphi-Quellcode:
library commdll;

uses
  SysUtils,
  Classes,
  Dialogs;

{$R *.res}

procedure GetCommand(CmdStr: String; SockId: Integer); stdcall;
begin
  ShowMessage('yes');
end;

exports
  GetCommand;

begin
end.

StanY 27. Okt 2004 15:22

Re: Dll zur Laufzeit verändern?
 
Leider immer noch nicht \:.

Dax 27. Okt 2004 15:30

Re: Dll zur Laufzeit verändern?
 
Da fällt mir grade ein: Strings dürfen einer DLL nicht direkt übergeben werden, sondern nur als PChar, oder durch einbindung von ShareMem. Versuch' mal eines von beiden...

StanY 27. Okt 2004 15:37

Re: Dll zur Laufzeit verändern?
 
Ich habe es nun so gemacht, dass gar nichts übergeben oder verlangt wird. Selber Fehler beim Aufrufen der Dll-Prozedur. \:

tommie-lie 27. Okt 2004 16:28

Re: Dll zur Laufzeit verändern?
 
Zitat:

Zitat von StanY
Delphi-Quellcode:
procedure TfrmMain.LoadDll(DllName: String);
var
  Handle: THandle;
begin
  //Dll wird nun eingebunden
  Handle := LoadLibrary(PChar(DllName));
  if (Handle <> 0) then begin
    GetCommand := GetProcAddress(Handle,'GetCommand');
  end;
  FreeLibrary(Handle); // <---
end;

Na du bist lustig, gibst die Bibliothek wieder frei, bevor du sie aufrufst :mrgreen:
Du kannst entweder FreeLibrary() ganz weglassen, Windows kümmert sich beim Beenden des Programmes automatisch um das freigeben aller Ressourcen, auch der DLLs. Da das aber in deinem Fall nicht praktikabel ist, solltest du das Handle der DLL als globale Variable deklarieren und eine zusätzliche UnloadDLL() implementieren, die das Handle mit FreeLibrary wieder freigibt. Dann kannst du in deinem Programm mit LoadDLL(URLfuerDLL) die DLL laden und mit UnloadDLL() wieder entladen und gleich darauf eine andere DLL laden.
Du musst nur sicher gehen, daß zwischen dem Entladen und dem Laden der DLL keine Funktion aus dieser DLL aufgerufen wird.

StanY 27. Okt 2004 16:37

Re: Dll zur Laufzeit verändern?
 
Mh, aber ich würde es gerne so machen, dass er die DLL bei Programm start lädt, und beim Beenden wieder entlädt. (Wird ja automatisch gemacht)

Desweiteren soll er, wenn er den Befehl bekommt, die DLL während des Laufens neu laden.

Sie soll aber permanent verwendbar sein.

Wie geht das? - Ich hoffe ihr versteht was ich meine \:

Btw. Ich dachte, das Handle ist nur wichtig, um die DLL zu laden... nicht, um sie zu erhalten.

tommie-lie 27. Okt 2004 16:50

Re: Dll zur Laufzeit verändern?
 
Zitat:

Zitat von StanY
Mh, aber ich würde es gerne so machen, dass er die DLL bei Programm start lädt, und beim Beenden wieder entlädt. (Wird ja automatisch gemacht)

Desweiteren soll er, wenn er den Befehl bekommt, die DLL während des Laufens neu laden.

Dein erster Wunsch und dein zweiter widersprechen sich doch ein ganz klein wenig, oder? :gruebel:
Du kannst natürlich auch das alte Handle nicht freigeben und immer weiter neue DLLs laden, je nachdem wie oft du das machst geht dir dann aber mit der Zeit der virtuelle Adressbereich aus, um eine DLL zu laden.
Es empfiehlt sich daher bei plugin-artigen Konstruktionen (wie das hier ja eine ist), die DLL vor dem erneuten Laden zu entladen, damit die alte DLL nicht mehr im Speicher gehalten werden muss.

Zitat:

Zitat von StanY
Sie soll aber permanent verwendbar sein.

Solange die DLL nicht geladen ist, kann man sie nicht anwenden.

Zitat:

Wie geht das?
Beim Programmstart die Standard-DLL laden und wenn dann im Laufe des Programmes die DLL gewechselt werden soll, erst die alte entladen und anschließend die neue laden.

Zitat:

Zitat von StanY
Btw. Ich dachte, das Handle ist nur wichtig, um die DLL zu laden... nicht, um sie zu erhalten.

Ist es auch, das Handle kannst du nach dem Laden wegwerfen und brauchst es nie wieder, wenn du Windows die DLL automatisch freigeben lässt. Aber du hast ja mit FreeLibrary die DLL gleich wieder aus dem Speicher rausgeschmissen, nachdem du die Funktionen zugewiesen hast. Und wie soll etwas aufgerufen werden, was nicht mehr im Speicher ist? :zwinker:

StanY 27. Okt 2004 17:03

Re: Dll zur Laufzeit verändern?
 
Danke, es geht nun (:

Und wenn man es versteht, sit es auch irgendwie ganz einfach \: <:

tommie-lie 27. Okt 2004 17:18

Re: Dll zur Laufzeit verändern?
 
Zitat:

Zitat von StanY
Und wenn man es versteht, sit es auch irgendwie ganz einfach \: <:

Stimmt, ist mit allen Dingen so :mrgreen:

StanY 27. Okt 2004 17:26

Re: Dll zur Laufzeit verändern?
 
Kann ich mit einer Dll eigentlich auf Componenten im Main-Programm zugreifen? oO

Mh, ich frage, und probiere nicht selber, weil wenn nicht, lohnt sich ne DLL gar nicht.

Danke.

maximus Caesar 9. Nov 2004 18:37

Re: Dll zur Laufzeit verändern?
 
Dazu verwendest am besten OOP! Schreibst ein Objekt, das bei dll und Hauptprogramm gleich ist, und lässt es dir über ne Funktion der dll komplett zurückliefern!


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:58 Uhr.

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