| imho.ws |
![]() |
|
|
|
# 1 |
|
Member
Регистрация: 15.06.2003
Адрес: underneath it all
Пол: Male
Сообщения: 348
![]() ![]() ![]() |
Указатели в Delphi
Была написана программа для работы с данными, собственно с самими данными работает подключаемая dllка, исходно dll загружалась "статически" при загрузке программы. При изменении программы так, чтобы dll загружалась динамически вылазит ошибка "access violation".
Попытался разобраться с этим на простенких програмках так и не понял в чем глюк. Вот исходники прог на которых пытался разобраться: DLL: Код:
library dll;
uses
SysUtils, Classes, Windows, Math;
Type
Tdatabac = procedure(p1: pointer; p2: pointer; p3: pointer);
var
databac:tdatabac=nil;
{$R *.res}
Procedure init(adr:pointer); stdcall;
Begin
@databac:=adr;
End;
procedure simulate; stdcall;
var
t0,tx: integer;
datt, date, dati: double;
begin
t0:=gettickcount;
date:=0;
dati:=0;
while (gettickcount-t0)<1000 do
begin
datt:=gettickcount-t0;
date:=date+1;
dati:=date;
if @databac<>nil then databac(@datt,@date,@dati);
end;
end;
exports
simulate, init;
begin
end.
Код:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
Tgetdata = procedure(d1: PDouble; d2: PDouble; d3: PDouble);
var
Form1: TForm1;
datt, date, dati: array [1..10000] of double;
pn:integer;
getdata: Tgetdata;
implementation
{$R *.dfm}
procedure init(adr: pointer); stdcall; external 'dll.dll';
procedure simulate; stdcall; external 'dll.dll';
procedure getd(d1: PDouble; d2: PDouble; d3: PDouble);
begin
if d1<>nil then datt[pn]:=d1^;
date[pn]:=d2^;
dati[pn]:=d3^;
form1.memo1.Lines.Add(floattostr(datt[pn])+' '+floattostr(date[pn])+' '+floattostr(dati[pn]));
pn:=pn+1;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
simulate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
new(@getdata);
@getdata:=@getd;
init(@getdata);
pn:=1;
end;
end.
Код:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
Tgetdata = procedure(d1: PDouble; d2: PDouble; d3: PDouble);
type
Tsimulate = procedure;
type
Tinit = procedure(adr: pointer);
var
Form1: TForm1;
datt, date, dati: array [1..10000] of double;
pn:integer;
simulate : tsimulate;
getdata: Tgetdata;
init : Tinit;
LibHandle: HMODULE;
implementation
{$R *.dfm}
procedure getd(d1: PDouble; d2: PDouble; d3: PDouble);
begin
if d1<>nil then datt[pn]:=d1^;
date[pn]:=d2^;
dati[pn]:=d3^;
form1.memo1.Lines.Add(floattostr(datt[pn])+' '+floattostr(date[pn])+' '+floattostr(dati[pn]));
pn:=pn+1;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
@init := nil;
@simulate := nil;
LibHandle := LoadLibrary('dll.dll');
if LibHandle >= 32 then
begin
new(@getdata);
@getdata:=@getd;
init := tinit(GetProcAddress(LibHandle,'init'));
simulate := tsimulate(GetProcAddress(LibHandle,'simulate'));
if @init <> nil then init(@getdata);
if @simulate <> nil then simulate;
end;
while not application.Terminated do application.ProcessMessages;
FreeLibrary(LibHandle);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
pn:=1;
end;
end.
__________________
Сердце раскололось на тысячи искр, разжигая огонь угасающих глаз, бесконечно смотрящих на холодный свет звезд, не знающих страсти, любви и печали.(c)я |
|
|
|
|
# 2 |
|
Guest
Сообщения: n/a
|
У тебя в dll соглашение вызова функций stdcall. При статическом импорте ты указал его. При динамическом – нет. Т.е. определение процедурных типов у тебя должно выглядеть следующим образом:
Код:
Type Tgetdata = procedure(d1: PDouble; d2: PDouble; d3: PDouble) stdcall; type Tsimulate = procedure stdcall; type Tinit = procedure(adr: pointer) stdcall; |
|
|
# 3 |
|
Member
Регистрация: 15.06.2003
Адрес: underneath it all
Пол: Male
Сообщения: 348
![]() ![]() ![]() |
Это называется тупизм напал. Все перепробовал, а на это даже не глянул...
Спасибо!!!
__________________
Сердце раскололось на тысячи искр, разжигая огонь угасающих глаз, бесконечно смотрящих на холодный свет звезд, не знающих страсти, любви и печали.(c)я |
|
|