Caricare una DLL da una risorsa direttamente dalla memoria nelle applicazioni Delphi

Articolo idea di Mark E. Moss

L'articolo su come archiviare una DLL all'interno di un file exe del programma Delphi come risorsa spiega come spedire una DLL con il file eseguibile dell'applicazione Delphi come risorsa.

Le librerie a collegamento dinamico contengono codice o risorse condivisibili, offrono la possibilità a più applicazioni di condividere una singola copia di una routine (o risorsa) che hanno in comune.

Utilizzando i file di risorse (.RES), è possibile incorporare (e utilizzare) file audio, videoclip, animazioni e più in generale qualsiasi tipo di file binario in un eseguibile di Delphi.

Caricamento DLL dalla memoria

se una DLL memorizzata in un RES può essere utilizzata senza prima salvarla sul file system (disco rigido)

Secondo l'articolo Caricamento di una DLL dalla memoria di Joachim Bauch, questo è possibile.

Ecco come Joachim esamina il problema: Le funzioni API di Windows predefinite per caricare librerie esterne in un programma (LoadLibrary, LoadLibraryEx) funzionano solo con i file sul filesystem. È quindi impossibile caricare una DLL dalla memoria. Ma a volte hai bisogno esattamente di questa funzionalità (ad es. Non vuoi distribuire molti file o rendere più difficile lo smontaggio). Soluzioni alternative comuni per questi problemi sono scrivere prima la DLL in un file temporaneo e importarla da lì. Al termine del programma, il file temporaneo viene eliminato.

Il codice nell'articolo citato è C ++, il passo successivo è stato convertirlo in Delphi. Fortunatamente, questo è già stato fatto da Martin Offenwanger (l'autore di DSPlayer).

Il modulo di memoria di Martin Offenwanger è una versione estesa di Delphi (e anche Lazzaro) compatibile con il modulo di memoria C ++ di Joachim Bauch 0.0.1. Il pacchetto zip include il codice sorgente Delphi completo di MemoyModule (BTMemoryModule.pas). Inoltre c'è un Delphi e un campione inclusi per dimostrare come usarlo.

Caricamento di DLL da risorse dalla memoria

Se una DLL demo viene archiviata come risorsa utilizzando il file RC:

DemoDLL RCDATA DemoDLL.dll
var
ms: TMemoryStream;
rs: TResourceStream;
inizio
Se 0 FindResource (hInstance, 'DemoDLL', RT_RCDATA) poi
inizio
rs: = TResourceStream.Create (hInstance, 'DemoDLL', RT_RCDATA);
ms: = TMemoryStream.Create;
provare
ms.LoadFromStream (rs);
Posizione ms: = 0;
m_DllDataSize: = ms.Size;
mp_DllData: = GetMemory (m_DllDataSize);
ms.Read (mp_DllData ^, m_DllDataSize);
infine
ms.Free;
rs.Free;
fine;
fine;
fine;
var
btMM: PBTMemoryModule;
inizio
btMM: = BTMemoryLoadLibary (mp_DllData, m_DllDataSize);
provare
se btMM = zero poi Abort;
@m_TestCallstd: = BTMemoryGetProcAddress (btMM, 'TestCallstd');
if @m_TestCallstd = nil then Abort;
m_TestCallstd ('Questa è una chiamata Memory Dll!');
tranne
Showmessage ('Si è verificato un errore durante il caricamento della dll:' + BTMemoryGetLastError);
fine;
Se Assegnato (BTMM) poi BTMemoryFreeLibrary (BTMM);
fine;
  1. Avere / creare una DLL
  2. Memorizzare la DLL in un file RES
  3. Avere l'implementazione di BTMemoryModule.
  4. Prendi la DLL dalla risorsa e caricala direttamente in memoria.
  5. Utilizzare i metodi BTMemoryModule per eseguire la procedura dalla DLL in memoria.

BTMemoryLoadLibary in Delphi 2009, 2010, ...

"Il BTMemoryModule.pas collegato non funziona con Delphi 2009 (e presumo anche Delphi 2010).
Ho trovato una versione simile del file BTMemoryModule.pas qualche tempo fa e ho apportato modifiche in modo che funzioni con (almeno) Delphi 2006, 2007 e 2009. Il mio BTMemoryModule.pas aggiornato e un progetto di esempio sono su BTMemoryLoadLibary for Delphi> = 2009 "