AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials DLL aus Resource direkt aus dem Speicher laden und benutzen!

DLL aus Resource direkt aus dem Speicher laden und benutzen!

Ein Tutorial von Lyan · begonnen am 1. Okt 2012 · letzter Beitrag vom 29. Apr 2020
Antwort Antwort
Seite 1 von 2  1 2   
Lyan
Registriert seit: 5. Aug 2011
Hallo,

da ich wirklich lange danach gesucht habe und immer nur übermäßig langen, für mich unverständlichen Code stoß, hier mal eine Lösung:

Wie binde ich eine DLL als Resource ein?
  1. Editor öffnen und "<DemoNameAufruf> RCDATA <DemoDatei.dll>" hineinschreiben.
    Bsp.: DllDatei RCDATA MeineDll.dll
  2. Diese Datei als .RC-Datei speichern. (Bsp.: Resources.RC)
  3. CMD öffnen (Start->Ausführen->cmd.exe->Return) und in das Verzeichnis der .RC-Datei navigieren.
  4. In die Konsole eintippen: BRCC32 <rcDatei.RC>
    Bsp.: BRCC32 Resources.RC
  5. Nun sollte eine .RES-Datei im gleichen Verzeichnis entstanden sein.
  6. In einer Unit nun noch "{$R *.DFM} {$R <resourcename>.RES}" eintragen (Bsp.: {$R *.DFM} {$R Resources.RES}) und fertig.
    Bitte trage diese Compiler-Direktive nach der From direktive und vor dem Implementation Schlüsselwort ein.

Nun zum eigentlichen Threadthema, wie kann ich diese DLL nun aufrufen, ohne sie vorher auf dem Dateisystem zu droppen, also direkt aus dem Speicher laden?


Um die Datei aus den Resourcen zu laden:

Delphi-Quellcode:
var
  ms : TMemoryStream;
  rs : TResourceStream;
begin
  if 0 <> FindResource(hInstance, 'DllDatei', RT_RCDATA) then
  begin
    rs := TResourceStream.Create(hInstance, 'DllDatei', RT_RCDATA);
    ms := TMemoryStream.Create;
    try
      ms.LoadFromStream(rs);

      ms.Position := 0;
      m_DllDataSize := ms.Size;
      mp_DllData := GetMemory(m_DllDataSize);

      ms.Read(mp_DllData^, m_DllDataSize);
    finally
      ms.Free;
      rs.Free;
    end;
  end;
end;

Nun ist die DLL in den Speicher geladen!
So benutzt man die DLL nun:

Delphi-Quellcode:
var
  btMM: PBTMemoryModule;
begin
  btMM := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);
  try
    if btMM = nil then Abort;
    @m_TestCallstd := BTMemoryGetProcAddress(btMM, 'TestCallstd');
    if @m_TestCallstd = nil then Abort;
    m_TestCallstd('Das ist ein DLL-Speicher Aufruf!');
  except
    Showmessage(Ein Fehler ist enstanden bei Aufruf der DLL : ' + BTMemoryGetLastError);
end;
if Assigned(btMM) then BTMemoryFreeLibrary(btMM);
end;
Ich hoffe für den ein oder anderen war das eine Hilfe!


Quelle: http://delphi.about.com/od/windowssh...nto-memory.htm
Download .PAS: https://github.com/jasonpenny/democo...ter/dGinaTest/

Geändert von Lyan ( 1. Okt 2012 um 14:36 Uhr)
 
globetrotter77

 
Delphi 10.3 Rio
 
#2
  Alt 28. Apr 2020, 22:46
seltsam, eigentlich habe ich eine Antwort geschrieben, aber sie taucht nicht auf
  Mit Zitat antworten Zitat
globetrotter77

 
Delphi 10.3 Rio
 
#3
  Alt 29. Apr 2020, 00:35
sorry, aber das kann ja nicht die Lösung sein

Editor öffnen und "<DemoNameAufruf> RCDATA <DemoDatei.dll>" hineinschreiben.
Bsp.: DllDatei RCDATA MeineDll.dll
Diese Datei als .RC-Datei speichern. (Bsp.: Resources.RC)
CMD öffnen (Start->Ausführen->cmd.exe->Return) und in das Verzeichnis der .RC-Datei navigieren.
In die Konsole eintippen: BRCC32 <rcDatei.RC>
Bsp.: BRCC32 Resources.RC
Nun sollte eine .RES-Datei im gleichen Verzeichnis entstanden sein.
In einer Unit nun noch "{$R *.DFM} {$R <resourcename>.RES}" eintragen (Bsp.: {$R *.DFM} {$R Resources.RES}) und fertig.
Bitte trage diese Compiler-Direktive nach der From direktive und vor dem Implementation Schlüsselwort ein.

ich bin mir sicher, dass Delphi diese Möglichkeit bietet
  Mit Zitat antworten Zitat
DieDolly
 
#4
  Alt 29. Apr 2020, 00:37
Zitat:
sorry, aber das kann ja nicht die Lösung sein
Das klingt ziemlich falsch finde ich. Das dauert keine 2 Minuten und muss nur einmalig erledigt werden.

In der Zeit in der du hier auf eine Antwort wartest, hättest du das schon 10x erledigen können.

Geändert von DieDolly (29. Apr 2020 um 00:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

 
Delphi 10.3 Rio
 
#5
  Alt 29. Apr 2020, 08:57
Zitat:
sorry, aber das kann ja nicht die Lösung sein
Das klingt ziemlich falsch finde ich. Das dauert keine 2 Minuten und muss nur einmalig erledigt werden.
Warum sollte man das nur einmal erledigen müssen? Das muss man immer wieder machen wenn sich die Dll geändert hat.

Allerdings kann man sich ein Script schreiben oder ein Tool was das automatisch beim compilieren macht.
Ich erzeuge zum Beispiel dll's die nach ihrem compilieren einmal aufgerufen um einen Schlüssel für sich selber zu erstellen dann könnte die sich aber selber in eine resource packen.

Aber ich würde die Dll eh nicht als resource einbinden sondern auf irgend eine andere art hugepack nehmen. ZB. als konstante Daten oder in einer DB die alle Ressourcen des Projektes bündelt.

Aber, herzlichen Dank für das Tutorial.
Stefan

Geändert von Sinspin (29. Apr 2020 um 09:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

 
Delphi 10.2 Tokyo Professional
 
#6
  Alt 29. Apr 2020, 09:18
"u_dzDllLoader/ResourceDllLoader allow to access DLLs functions in a object oriented manner, the latter provides loading a DLL from the program’s resources rather than from disk (which is a hack, so beware that it might not work on the latest and greatest Windows version)"

https://blog.dummzeuch.de/dzlib/

Es funktioniert definitiv noch im aktuellen Windows 10 64 Bit. Aber nur für 32-Bit Programme und DLLs.
Thomas Mueller
  Mit Zitat antworten Zitat
hoika

 
Delphi 10.4 Sydney
 
#7
  Alt 29. Apr 2020, 10:00
Hallo,
Zitat:
Diese Datei als .RC-Datei speichern. (Bsp.: Resources.RC)
Ja, und das reicht, nix mit brcc!

Diese RC in das Projekt einbinden,
dann baut Delphi die RES bei jedem Compilieren selber zusammen.
Dank Make wird die RES nur neu erzeugt, wenn sich die Daten der RC ändern, hoffe ich.
Heiko
  Mit Zitat antworten Zitat
globetrotter77

 
Delphi 10.3 Rio
 
#8
  Alt 29. Apr 2020, 10:04
offensichtlich versteht niemand so richtig, worum es geht ... wahrscheinlich habe ich es nicht genau genug beschrieben.

also nochmal ganz langsam:
ich schreibe ein Programm, mit dem ich auf eine MySQL-Datenbank zugreifen will. Die Datenbank ist dabei eigentlich völlig egal - ich sag's nur.
deshalb lege ich eine Komponente vom Typ TFDConnection an
in dieser wähle ich die DriverID MySQL
von diesem Moment an will Delphi beim Compilieren eine DLL im Pfad finden
aus welchen Gründen auch immer ist scheinbar nur "libmariadb.dll" geeignet ... kann mir auch egal sein

ich rufe keine Funktion aus dieser DLL direkt auf, sondern nutze ausschließlich Delphi-Komponenten.
die Frage lautet nun:
kann ich Delphi irgendwie mitteilen, dass die DLL direkt geladen und quasi in der EXE mitgenommen wird oder nicht?
das ausschließliche Ziel lautet:
kann ich die EXE-Datei auf einen anderen Rechner übertragen, ohne die zusätzliche DLL auch mitzunehmen?
  Mit Zitat antworten Zitat
TiGü

 
Delphi 10.4 Sydney
 
#9
  Alt 29. Apr 2020, 10:50
Aha, das klingt doch schon anders.
Einfach die benötigten DLLs, z.B. libmariadb.dll, als Resource mit in deine EXE packen und beim Start und vor der Verbindung mit der Datenbank aus der Resource rausholen und irgendwo temporär hinspeichern, wo dein Programm Schreibrechte hat (bspw. %APPDATA%).
Dann ziehst du dir noch eine Instanz von TFDPhysMySQLDriverLink auf das Formular (oder erzeugst es zur Laufzeit - je nachdem wie du deine TFDConnection behandelst.) und gibst über die Property VendorLib den Pfad zur deiner temporär abgespeicherten DLL an.
http://docwiki.embarcadero.com/Libra...Link.VendorLib
  Mit Zitat antworten Zitat
Andreas13

 
Delphi XE5 Professional
 
#10
  Alt 29. Apr 2020, 11:00
Eine ähnliche Lösung wurde vor langer Zeit im Forum "Delphi-Treff" veröffentlicht: https://www.delphi-treff.de/tutorial...tatur-hooks/6/. Vielleicht funktioniert es immer noch.
Gruß, Andreas
  Mit Zitat antworten Zitat
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:29 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