Załaduj bibliotekę DLL z zasobu bezpośrednio z pamięci

Artykuł autorstwa Marka E. Mech

W artykule, jak przechowywać bibliotekę DLL w pliku exe programu Delphi jako zasób, wyjaśniono, jak wysłać bibliotekę DLL z plikiem wykonywalnym aplikacji Delphi jako zasobem.

Biblioteki linków dynamicznych zawierają współdzielony kod lub zasoby, umożliwiają wielu aplikacjom współdzielenie jednej kopii procedury (lub zasobu), które mają wspólną.

Za pomocą pliki zasobów (.RES), możesz osadzać (i używać) pliki dźwiękowe, klipy wideo, animacje i ogólnie wszelkiego rodzaju pliki binarne w pliku wykonywalnym Delphi.

Ładowanie bibliotek DLL z pamięci

jeśli biblioteka DLL przechowywana w RES może być używana bez uprzedniego zapisania jej w systemie plików (dysk twardy)

Według artykułu Ładowanie biblioteki DLL z pamięci autor: Joachim Bauch, jest to możliwe.

Oto jak Joachim patrzy na problem: Domyślne funkcje API systemu Windows do ładowania zewnętrznych bibliotek do programu (LoadLibrary, LoadLibraryEx) działają tylko z plikami w systemie plików. Dlatego niemożliwe jest załadowanie biblioteki DLL z pamięci. Ale czasami potrzebujesz dokładnie tej funkcji (np. Nie chcesz dystrybuować dużej liczby plików ani utrudniać dezasemblacji). Typowe obejścia tego problemu polegają na zapisaniu biblioteki DLL do pliku tymczasowego i zaimportowaniu go stamtąd. Po zakończeniu programu plik tymczasowy zostanie usunięty.

instagram viewer

Kodem we wspomnianym artykule jest C ++, następnym krokiem było przekonwertowanie go na Delphi. Na szczęście już to zrobił Martin Offenwanger (autor DSPlayer).

Moduł pamięci autor: Martin Offenwanger to rozszerzona wersja C ++ Joachima Baucha zgodna z Delphi (a także Lazarus) Moduł pamięci 0.0.1. Pakiet zip zawiera pełny kod źródłowy Delphi MemoyModule (BTMemoryModule.pas). Ponadto dołączono Delphi i próbkę, aby zademonstrować, jak z niego korzystać.

Ładowanie bibliotek DLL z zasobów z pamięci

Jeśli demo DLL jest przechowywany jako zasób przy użyciu pliku RC:

DemoDLL RCDATA DemoDLL.dll
var
ms: TMemoryStream;
rs: TResourceStream;
zaczynać
gdyby 0 <> FindResource (hInstance, 'DemoDLL', RT_RCDATA) następnie
zaczynać
rs: = TResourceStream. Utwórz (hInstance, 'DemoDLL', RT_RCDATA);
ms: = TMemoryStream. Stwórz;
próbować
ms. LoadFromStream (rs);
ms. Pozycja: = 0;
m_DllDataSize: = ms. Rozmiar;
mp_DllData: = GetMemory (m_DllDataSize);
ms. Odczyt (mp_DllData ^, m_DllDataSize);
Wreszcie
ms. Darmowy;
rs. Darmowy;
koniec;
koniec;
koniec;
var
btMM: PBTMemoryModule;
zaczynać
btMM: = BTMemoryLoadLibary (mp_DllData, m_DllDataSize);
próbować
jeśli btMM = zeronastępnie Anulować;
@m_TestCallstd: = BTMemoryGetProcAddress (btMM, 'TestCallstd');
jeśli @m_TestCallstd = zero, to Przerwij;
m_TestCallstd („To jest wywołanie pamięci Dll!”);
z wyjątkiem
Showmessage („Wystąpił błąd podczas ładowania biblioteki dll: '+ BTMemoryGetLastError);
koniec;
gdyby Przypisany (btMM) następnie BTMemoryFreeLibrary (btMM);
koniec;
  1. Mieć / utworzyć bibliotekę DLL
  2. Zapisz bibliotekę DLL w pliku RES
  3. Mieć Implementacja BTMemoryModule.
  4. Pobierz bibliotekę DLL z zasobu i załaduj ją bezpośrednio do pamięci.
  5. Użyj metod BTMemoryModule, aby wykonać procedurę z biblioteki DLL w pamięci.

BTMemoryLoadLibary w Delphi 2009, 2010,...

„Połączony BTMemoryModule.pas nie działa z Delphi 2009 (i założyłbym również Delphi 2010).
Znalazłem podobną wersję pliku BTMemoryModule.pas jakiś czas temu i wprowadziłem zmiany, aby działała z (przynajmniej) Delphi 2006, 2007 i 2009. Mój zaktualizowany BTMemoryModule.pas i przykładowy projekt znajdują się pod adresem BTMemoryLoadLibary dla Delphi> = 2009"