Witam.
Czy ktoś z Was korzystał z BTMemoryModule_0.0.1, który może służyć do ładowania
dll'ek z zasobów do pamięci? Pytam, bo kombinuje jakby tutaj załadować sobie z
zasobów do pamięci bass.dll albo fmod.dll. Jednak obie zwracają errory przy
próbie wywołania prostej funkcji GetVersion czyli BASS_GetVersion dla biblioteki
bass.dll albo FSOUND_GetVersion dla fmod.dll. W przypadku tej pierwszej moduł
BTMemory nie zwraca żadnego konkretnego komunikatu o błędzie. W przypadku fmoda
jest to 'FinalizeSections: VirtualProtect failed'. Specialnie dla testów
dołączyłem do zasobów w pliku dane.res, testową dllke DemoDLL.dll, która jest
dołączona do źródeł modułu. A w pliku dane.rc zasoby zdefiniowane są tak:
bass_lib rcdata "bass.dll"
demo_lib rcdata "demodll.dll"
Kod mojego modułu poniżej. Kod w DemoDLLBtnClick działa poprawnie i DemoDll.dll
wywołuje dwa MessageBox'y z tekstem 'This is a Dll Memory call!' - natomiast to
co jest w BassDllBtnClick powoduje wyjatek Acess Violation - a po skompilowaniu
pokazuje error 'An error occoured while loading the dll: ' i tyle. Stąd pytanie
czy ten moduł będzie działał tylko z bibliotekami skompilowanymi w Delphi? No a
może akurat bass.dll jest jakoś tak stworzona, że działa poprawnie - załadowana
tylko i wyłącznie z dysku? Jakby ktoś mógł się przyjerzeć BT Memory to jest na:
http://www.joachim-bauch.de/tutorials/load_dll_memory.html
http://www.dsplayer.de/open_source_projects/BTMemoryModule.zip
A może znacie inny sposób na zamieszczenie biblioteki dll w zasobach - po czym
załadowanie jej do pamięci, tak aby działały wszystkie funkcje w niej zawarte?
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, xpman, BTMemoryModule;
type
TTestCallstd = procedure(f_Text: PChar); stdcall;
TTestCallcdel = procedure(f_Text: PChar); cdecl;
TBASS_GetVersion = function : DWORD; stdcall;
TForm1 = class(TForm)
BassDllBtn: TButton;
DemoDLLBtn: TButton;
procedure FormDestroy(Sender: TObject);
procedure BassDllBtnClick(Sender: TObject);
procedure DemoDLLBtnClick(Sender: TObject);
private
public
m_TestCallstd: TTestCallstd;
m_TestCallcdel: TTestCallcdel;
m_BassGetVer : TBass_GetVersion;
mp_DllData: Pointer;
m_DllDataSize: Integer;
mp_MemoryModule: PBTMemoryModule;
MemoryStream: TMemoryStream;
Res_Stream : TResourceStream;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{$R dane.res}
procedure TForm1.BassDllBtnClick(Sender: TObject);
begin
Res_Stream := TResourceStream.Create(Hinstance, 'bass_lib', RT_RCDATA);
MemoryStream := TMemoryStream.Create;
MemoryStream.LoadFromStream(Res_Stream);
MemoryStream.Position := 0;
m_DllDataSize := MemoryStream.Size;
mp_DllData := GetMemory(m_DllDataSize);
MemoryStream.Read(mp_DllData^, m_DllDataSize);
MemoryStream.Free;
// Sama ta linia poniżej już generuje wyjątek bez konkrentnego tekstu błędu
mp_MemoryModule := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);
try
if mp_MemoryModule = nil then
Abort;
@m_BassGetVer := BTMemoryGetProcAddress(mp_MemoryModule, 'BASS_GetVersion');
ShowMessage(IntToStr(m_BassGetVer));
except
Showmessage('An error occoured while loading the dll: ' +
BTMemoryGetLastError);
end;
end;
procedure TForm1.DemoDLLBtnClick(Sender: TObject);
begin
Res_Stream := TResourceStream.Create(Hinstance, 'demo_lib', RT_RCDATA);
MemoryStream := TMemoryStream.Create;
MemoryStream.LoadFromStream(Res_Stream);
MemoryStream.Position := 0;
m_DllDataSize := MemoryStream.Size;
mp_DllData := GetMemory(m_DllDataSize);
MemoryStream.Read(mp_DllData^, m_DllDataSize);
MemoryStream.Free;
mp_MemoryModule := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);
try
if mp_MemoryModule = nil then
Abort;
@m_TestCallstd := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallstd');
if @m_TestCallstd = nil then
Abort;
@m_TestCallcdel := BTMemoryGetProcAddress(mp_MemoryModule, 'TestCallcdel');
if @m_TestCallcdel = nil then
Abort;
m_TestCallstd('This is a Dll Memory call!');
m_TestCallcdel('This is a Dll Memory call!');
except
Showmessage('An error occoured while loading the dll: ' +
BTMemoryGetLastError);
end;
if mp_MemoryModule <> nil then
BTMemoryFreeLibrary(mp_MemoryModule);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeMemory(mp_DllData);
end;
end.