Zostanę znienawidzony za swoją niekompetencję na forum, jednak zmuszony jestem ponownie prosić o pomoc, lub podpowiedź w związku z projektem z list jednokierunkowych w bibliotece DLL.
Jako, że mimo pokonania magicznego błędu wcześniej nadal miałem problemy z projektem, postanowiłem napisać go od nowa i testować wszystkie małe fragmenty po kolei. Stworzyłem więc nową bibliotekę DLL zawierającą tylko procedury "Dodaj rekord do listy na pierwszym miejscu"(wiem, mało elegancko, ale chcę zacząć od czegoś gdzie w procedurze nie będzie błędu ze względu na prostotę i później to poprawić mając wersję podstawową, która na pewno działa) oraz "Usuń pierwszy rekord z listy".
W nowym unicie stworzyłem pojedynczy przycisk wywołujący trzy razy funkcję dodającą i dwukrotnie usuwającą, jednak przy drugim (i kolejnych) uruchomieniu usuwania procedura usuwająca zachowuje się jakby wskaźnik na listę wskazywał nil
(wywołuje okienko które miało się pokazywać przy próbie usunięcia elementu którego nie ma), czyli jakby moja zmienna first
nigdy nie zmieniła swojej wartości.
Podejrzewam, że nie rozumiem jak owy first
jest przekazywany między unitem, a DLL.
Serdecznie dziękuję za wszelkie podpowiedzi!
A i tak, wszystko kompiluje bez żadnych błędów.
DLLka
library ProjectDLL;
uses
System.SysUtils,
System.Classes,
Vcl.Dialogs,
Baza;
procedure Dodajdolisty(elem:Tdane);stdcall;
var t:wsk;
begin
try
if first=nil then t:=nil else t:=first^.next;
new(first);
first^.dane:=elem;
first^.next:=t;
except
showmessage('Nieudane dołączanie elementu do listy.');
end;
end;
procedure Usunpierwszyzlisty();stdcall;
var t:wsk;
begin
try
if first=nil then showmessage('Brak elementu do usunięcia.')
else
begin
t:=first;
first:=first^.next;
dispose(t);
end;
except
showmessage('Nieudane usunięcie elementu.');
end;
end;
exports
Dodajdolisty index 1,
Usunpierwszyzlisty index 2;
begin
end.
I główny Unit
unit Baza;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
type
TDane=record
ocena:byte;
end;
wsk=^lista;
lista=record
dane:tdane;
next:wsk;
end;
var first:wsk; DLL:Thandle;
Dodaj:procedure(rekord:tdane);stdcall;
Usun:procedure();stdcall;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var elem:tdane;
begin
DLL:=loadlibrary('DLL');
try
first:=nil;
@Dodaj:=getprocaddress(DLL,pchar(1));
@Usun:=getprocaddress(DLL,pchar(2));
if (@Dodaj=nil)or(@Usun=nil) then raise Exception.Create('Nie znaleziono procedury w bibliotece.');
elem.ocena:=5;
Dodaj(elem);
elem.ocena:=7;
Dodaj(elem);
elem.ocena:=9;
Dodaj(elem);
Usun();
Usun();
finally
freelibrary(DLL);
end;
end;
end.