Показать сообщение отдельно
  #1  
Старый 20.06.2011, 18:44
Faust777 Faust777 вне форума
Прохожий
 
Регистрация: 20.06.2011
Сообщения: 3
Репутация: 10
По умолчанию Ошибка инициализации dll из потока памяти

Здравствуйте!

Прошу помощи. Задача следующая:
1. Необходимо получить с сервера dll и поместить ее в MemoryStream. Этот шаг проходит успешно.
2. Инициализировать dll и использовать ее функцию для расчетов. Для работы с dll из потока памяти используется модуль BTMemoryModule.

Среда разработки Delphi 7.

Ошибка возникает после приема dll, в поток памяти на стороне клиента, во время ее инициализации в строчке:
PHP код:
mp_MemoryModule := BTMemoryLoadLibary(mp_DllDatam_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
WindowsMessagesSysUtilsVariantsClassesGraphicsControlsForms,
  
DialogsGaugesStdCtrls,IniFilesExtCtrlsjpeg,VMFScktComp;


type
  Tvm
=function (b,d:real;t:integer):double;stdcall;

  
TForm3 = class(TForm)
    
Gauge1TGauge;
    
Timer1TTimer;
    
Label1TLabel;
    
Image1TImage;
    
LabelIP_servTLabel;
    
LabelPort_servTLabel;
    
Label2TLabel;
    
EditIP_servTEdit;
    
EditPort_servTEdit;
    
EditPIN_codeTEdit;
    
ButtonConnectTButton;
    
ClientSocket1TClientSocket;
    
procedure Timer1Timer(SenderTObject);
    
procedure ButtonConnectClick(SenderTObject);
    
procedure ClientSocket1Connect(SenderTObject;
      
SocketTCustomWinSocket);
    
procedure ClientSocket1Read(SenderTObjectSocketTCustomWinSocket);

  private
    
Reciving:boolean;
    
mem_stream1:TMemoryStream;
    
DataSize:integer;
  public
  
end;



var
  
Form3TForm3;
  
  
VM_func:TVMF;// объектная переменная

  
vm1:Tvm;
  
  
mp_DllDataPointer;  // *-vars for load dll
  
m_DllDataSizeInteger;
  
mp_MemoryModulePBTMemoryModule;   //-*

  
procedure load_dll(mem_stream:TMemoryStream);// процедура загрузки dll, собственно в ней и возникает ошибка

implementation

uses math_module
,main;

{
$R *.dfm}



procedure TForm3.Timer1Timer(SenderTObject);
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(TForm3Form3);
  
Application.Run;
end

Человеку, который поможет решить проблему заплачу 10$.
Ответить с цитированием