Ошибка инициализации dll из потока памяти
Здравствуйте!
Прошу помощи. Задача следующая:
1. Необходимо получить с сервера dll и поместить ее в MemoryStream. Этот шаг проходит успешно.
2. Инициализировать dll и использовать ее функцию для расчетов. Для работы с dll из потока памяти используется модуль BTMemoryModule.
Среда разработки Delphi 7.
Ошибка возникает после приема dll, в поток памяти на стороне клиента, во время ее инициализации в строчке:
PHP код:
mp_MemoryModule := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);
Ошибка следующая:
Project GVM.exe raised exception class EAccessViolation with message 'Access Violation at adress 00401D2D in module 'GMV.exe.' Write of adress 00000001'.
Тестировал в отдельном проекте там все работает безупречно, но в тестовом всего 2 формы, на одной все это дело происходит, а вторая пустая.
Выкладываю исходник модуля, где возникает ошибка, закомментил строчку, где происходит ошибка:
PHP код:
unit Initialize;
interface
uses BTMemoryModule, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Gauges, StdCtrls,IniFiles, ExtCtrls, jpeg,VMF, ScktComp;
type Tvm=function (b,d:real;t:integer):double;stdcall;
TForm3 = class(TForm) Gauge1: TGauge; Timer1: TTimer; Label1: TLabel; Image1: TImage; LabelIP_serv: TLabel; LabelPort_serv: TLabel; Label2: TLabel; EditIP_serv: TEdit; EditPort_serv: TEdit; EditPIN_code: TEdit; ButtonConnect: TButton; ClientSocket1: TClientSocket; procedure Timer1Timer(Sender: TObject); procedure ButtonConnectClick(Sender: TObject); procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private Reciving:boolean; mem_stream1:TMemoryStream; DataSize:integer; public end;
var Form3: TForm3; VM_func:TVMF;// объектная переменная
vm1:Tvm; mp_DllData: Pointer; // *-vars for load dll m_DllDataSize: Integer; mp_MemoryModule: PBTMemoryModule; //-*
procedure load_dll(mem_stream:TMemoryStream);// процедура загрузки dll, собственно в ней и возникает ошибка
implementation
uses math_module,main;
{$R *.dfm}
procedure TForm3.Timer1Timer(Sender: TObject); var g:pointer; IniFile : TIniFile; Path:String; start,num_points:integer; begin
Path:=Application.ExeName; Path:=ExtractFileDir(Path); if Path[Length(Path)]<>'\' then Path:=Path+'\'; IniFile:=TIniFile.Create(Path+'config.ini');
try start:=StrToInt(IniFile.ReadString ('Params','Start_iniz','0')); num_points:=StrToInt(IniFile.ReadString ('Params','Num_points','4000')); except end; IniFile.Free; Form3.Timer1.Enabled:=false; VM_func:=TVMF.Create(1.0,2.0,1.0,2.0,start,num_points);
BTMemoryFreeLibrary(mp_MemoryModule) ; FreeMemory(mp_DllData);
Application.CreateForm(TForm1, Form1); G:=@Application.MainForm; Pointer(G^) := Form1; Form1.Show; Form3.Free;
end;
procedure TForm3.ButtonConnectClick(Sender: TObject); begin ClientSocket1.Host:=Form3.EditIP_serv.Text; ClientSocket1.Port:=StrToInt(Form3.EditPort_serv.Text); ClientSocket1.Active:=true; end;
procedure TForm3.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin ClientSocket1.Socket.SendText(Form3.EditPIN_code.Text); end;
procedure TForm3.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var s, sl: String; g:pointer; begin
s:= Socket.ReceiveText; if Reciving then begin mem_stream1.Write(s[1], length(s)); if mem_stream1.Size=DataSize then begin Reciving:=false; load_dll(mem_stream1); ClientSocket1.Active:=false; Timer1.Enabled:=true; exit; end; end; if copy(s, 1, 5)='Size:' then begin sl:=copy(s, 6, Pos(#0, s)-6); DataSize:=StrToInt(sl); Delete(s, 1, Pos(#0, s)); Reciving:=true; mem_stream1:=TMemoryStream.Create; mem_stream1.Write(s[1], length(s)); end; end;
// В этой процедуре возникает ошибка procedure load_dll(mem_stream:TMemoryStream); begin mem_stream.Position := 0; m_DllDataSize := mem_stream.Size; mp_DllData := GetMemory(m_DllDataSize); mem_stream.Read(mp_DllData^, m_DllDataSize); mem_stream.Free;
mp_MemoryModule := BTMemoryLoadLibary(mp_DllData, m_DllDataSize);// ЗДЕСЬ ОШИБКА! try if mp_MemoryModule=nil then exit; @vm1:=BTMemoryGetProcAddress(mp_MemoryModule,'vm');
if @vm1=nil then exit;//Функция не найдена except end;
end; end.
И исходник модуля, который инициализирует запуск приложения, чтобы видели, что вообще имеется в программе:
PHP код:
program GVM;
uses Forms, BTMemoryModule in 'BTMemoryModule.pas', Main in 'Main.pas' {Form1}, math_module in 'math_module.pas', Config in 'Config.pas' {Form2}, Initialize in 'Initialize.pas' {Form3}, VMF in 'VMF.pas', FAM in 'FAM.pas', EvalThread in 'EvalThread.pas', ConnectServer in 'ConnectServer.pas';
{$R *.res}
begin Application.Initialize; Application.Title := 'FAM Generator'; Application.CreateForm(TForm3, Form3); Application.Run; end.
Человеку, который поможет решить проблему заплачу 10$.
|