Witam, uczę się pisać w Delphi, obecnie do wykonania mam projekt "Bazy danych"(Gier w moim wypadku, z danymi typu nazwa, studio itp.), który ma operować na listach jednokierunkowych, a jego "silnik" (dodawanie, usuwanie z listy, zapis, wczytanie pliku typowanego) ma się znajdować wewnątrz Dynamicznej Biblioteki (DLL).
Gdy próbuję wykonać polecenia z biblioteki (Dodania do listy elementów stringgrida, a później ich zapisu do pliku) otrzymuję taki komunikat: First chance exceptation at $048AD82A. Exceptation class $C0000005 with message 'acces violation at 0x048ad82a: read of address 0x00000000'. Process Gry.exe(7256) i nie rozumiem dlaczego. Dzieje się tak niezależnie od tego, czy stringgrid jest pusty (poza pierwszym wierszem nagłówkowym), czy wypełniony prawidłowymi danymi.
Tak wyglądają funkcje w dll które wykonuję (debuger zaznacza zawsze pierwszą linijkę funkcji (po begin, try itp.) niezależnie od tego co się w niej znajduje.
type
wskaznik = ^lista;
TDane= record
nazwa, studio:shortstring;
gatunek:shortstring;
data:TDateTime;
ocena:Single;
end;
lista = record
dane: TDane;
next: wskaznik;
end;
{$R *.res}
////////// ////////// ////////// ////////// //////////
function Dodaj (var first: wskaznik; info: TDane):boolean; stdcall;
var
poprz,t:wskaznik;
begin
try
if first=nil then
begin
new(first);
first^.dane:=info;
first^.next:=nil;
end
else
begin
t:=first;
if info.nazwa<=first^.dane.nazwa then
begin
new(t);
t^.dane:=info;
t^.next:=first;
end
else
begin
while (t^.next<>nil)and(t^.dane.nazwa<info.nazwa) do
begin
t:=t^.next;
end;
poprz:=t;
new(t);
t^.dane:=info;
t^.next:=poprz^.next;
poprz^.next:=t;
end;
end;
result:=true;
except
result:=false;
end;
end;
////////// ////////// ////////// ////////// //////////
function Usun (var usuwany,first:wskaznik):boolean;stdcall;
var t, n:wskaznik;
begin
try
t:=first;
while t^.next<>usuwany do
begin
t:=t^.next;
if t^.next=nil then raise Exception.Create('Nie znaleziono elementu do usunięcia.');
end;
n:=t;
t:=t^.next;
n^.next:=t^.next;
dispose(t);
result:=true;
except
result:=false;
end;
end;
function Zapisz (var first:wskaznik; nazwa:shortstring):boolean;stdcall;
var elem:TDane; fp:file of TDane;
begin
begin
try
if first=nil then raise Exception.Create('Brak danych do zapisu.');
AssignFile(fp,nazwa);
try
rewrite(fp);
while first<>nil do
begin
elem:=first^.dane;
write(fp,elem);
Usun(first,first);
end;
finally
closefile(fp);
end;
result:=true;
except
result:=false;
end;
end
end;
exports
Dodaj index 1,
Usun index 2,
Zapisz index 4;
begin
end.
A tak procedura i funkcje używane w głównym unicie (jest jeszcze zdarzenie oncreate dla Form1 gdzie `first:=nil`.
type
wskaznik = ^lista;
TDane = record
nazwa,studio:shortstring;
gatunek:shortstring;
data:TDateTime;
ocena:Single;
end;
lista = record
dane:TDane;
next:wskaznik;
end;
var
dana:TDane;first,current:wskaznik; xxx : HModule;
insert:function(start:wskaznik;info:TDane):boolean;stdcall;
save:function(start:wskaznik;nazwa:shortstring):boolean;stdcall;
implementation
{$R *.dfm}
///////////////////////////////////////////////////////////////////////////////////////////
function sprdata(data:shortstring):boolean;
begin
try
strtodate(data);
result:=true;
except
result:=false;
end;
end;
function sprocena(ocena:shortstring):boolean;
begin
try
strtofloat(ocena);
result:=true;
except
result:=false;
end;
end;
procedure TForm1.Zapisz(Sender: TObject);
var
elem:TDane;
i,n:integer;
begin
try
xxx:=loadlibrary('DLLTest.dll');
if xxx<hinstance_error then raise Exception.Create('Nie można załadować biblioteki.');
insert:=getprocaddress(xxx,pchar(1));
save:=getprocaddress(xxx,pchar(4));
if (@save = nil)or(@insert = nil) then raise Exception.Create('Nie mozna załadowac funkcji.');
if (stringgrid1.Cells[0,stringgrid1.RowCount-1]='')and(stringgrid1.Cells[1,stringgrid1.RowCount-1]='')and(stringgrid1.Cells[2,stringgrid1.RowCount-1]='')and(stringgrid1.Cells[3,stringgrid1.RowCount-1]='')and(stringgrid1.Cells[4,stringgrid1.RowCount-1]='') then n:=stringgrid1.RowCount-1
else n:=stringgrid1.RowCount;
i:=1;
while i<n do
begin
if sprdata(stringgrid1.Cells[3,i])=false then raise Exception.Create('Wiersz '+inttostr(i)+' zawiera niepoprawną datę.');
if sprocena(stringgrid1.Cells[4,i])=false then raise Exception.Create('Wiersz '+inttostr(i)+' zawiera niepoprawną ocenę.');
i:=i+1;
end;
i:=1;
while i<n do
begin
with elem do
begin
nazwa:=stringgrid1.Cells[0,i];
studio:=stringgrid1.Cells[1,i];
gatunek:=stringgrid1.Cells[2,i];
data:=strtodate(stringgrid1.Cells[3,i]);
ocena:=strtofloat(stringgrid1.Cells[4,i]);
end;
insert(first,elem);
i:=i+1;
end;
save(first,'Baza');
finally
freelibrary(xxx);
end;
end;
Z góry dziękuję za wszelką pomoc.