Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #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$.

Последний раз редактировалось Faust777, 20.06.2011 в 19:20.
Ответить с цитированием
  #2  
Старый 20.06.2011, 21:14
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Пользовался как то этой приблудой для загрузки dll, тоже хотелось выпендреться. В итоге плюнул и отдал всё на откуп операционке. Деньги оставь себе (на пиво).
Ответить с цитированием
  #3  
Старый 20.06.2011, 22:53
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Топай на wasm.ru там куча сорсов и чтива по "хитрооопому" запуску кода.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #4  
Старый 21.06.2011, 09:11
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

какая основная цель: выполнение расчетов путем получения библиотеки с сервера и вызов ее функция обычным путем или же работа с библиотекой в "потоке памяти"?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 22.06.2011, 08:43
Faust777 Faust777 вне форума
Прохожий
 
Регистрация: 20.06.2011
Сообщения: 3
Репутация: 10
По умолчанию

Основная цель- это подключить полученную с сервера dll, которая принимается в поток памяти.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:46.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter