Lista jednokierunkowa

0

Zabrałem się za tą nieszczęsną listę, ale niestety mi nie chce działać. Wyskakuje mi taki błąd przy dodawaniu do listy:
user image
Oto kod z dll, ponieważ to właśnie w nim bym chciał zrobić tą listę.:

type
 PElement = ^TElement;
 TElement = record
   Next: PElement;
   Nazwa: string[30];
   Cena:  currency;
   Gatunek: string[15];
   Platforma: string[10];
 end;

var
  poczatek:PElement;
  c: integer=0;

//POCZĄTEK LISTY
 procedure start; stdcall;
 begin
     poczatek := nil;
 end;
 //DODAWANIE DO LISTY
procedure dodajl(naz:string;cen:currency;gat:string;pla:string); stdcall;
 var
  nowy: PElement;
 begin
 inc(c);
    New(nowy);
    nowy^.Next := nil;
    nowy^.Nazwa := naz;
    nowy^.Cena := cen;
    nowy^.Gatunek := gat;
    nowy^.Platforma :=pla;
    if poczatek = nil then
     begin
      poczatek := nowy;
     end else begin
      while poczatek^.next <> nil do poczatek := poczatek^.next;
      poczatek^.next := nowy;
   end;
 end;
exports  // eksportuj procedurę
  dodajl,start;

I funkcja która z korzysta z dll:

procedure start; external 'dll.dll';
procedure dodajl(naz:string;cen:currency;gat:string;pla:string); external 'dll.dll';

(...)

start;
dodajl(edit1.Text,strtocurr(edit2.Text),edit3.Text,edit4.Text);

Skoro już teraz mam taki problem, to co to będzie przy sortowaniu ;D
Wie ktoś jak to naprawić?

1

i oczywiście przeczytałeś jebitne ostrzeżenie, które Ci się w głównym pliku projektu DLL wyświetliło jako komentarz. I oczywiście wiesz, że przekazywanie string do dll jest problematyczne. I na koniec wiesz, że jak co najmniej dwa razy wywołasz dodajl to stracisz uchwyt do głowy listy

1

To ja może przypomnę, bo faktycznie można go nie zauważyć:

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

Tak więc: albo dodaj moduł ShareMem na pierwsze miejsce, albo skorzystaj z innych łańcuchów jak ShortString czy PChar (i zawsze czytaj to, co ma Ci do powiedzenia środowisko czy kompilator);

Jeśli nie ogarniasz dalej list to poczytaj ten artykuł - jest w nim dość dobrze opisana lista jednokierunkowa; Jednak jeśli nie zaczniesz dobrze formatować kodu, to będziesz miał w kółko problemy;

0

Dobra, zrezygnowałem z dll i wsadziłem to do normalnego pliku .pas, dzięki czemu ten błąd już nie wyskoczył na tym etapie. Natomiast pojawił się ponownie (ta sama treść, inne cyferki) przy wczytywaniu danych z listy do stringgrida. Oto kod:

type
 PElement = ^TElement;
 TElement = record
   Next: PElement;
   Nazwa: string[30];
   Cena:  string[15];
   Gatunek: string[15];
   Platforma: string[10];
 end;
(..)
var
  p:PElement;
  x:integer;
(..)
{*******************DODAJ*******************}
procedure dodajl(naz:string;cen:string;gat:string;pla:string);
 var
  nowy: PElement;
 begin
    New(nowy);
    nowy^.Next := p;
    nowy^.Nazwa := naz;
    nowy^.Cena := cen;
    nowy^.Gatunek := gat;
    nowy^.Platforma :=pla;
    p:=nowy;
 end;
(..)
{*******************STRINGGRID DO LISTY*******************}
procedure TForm2.Button6Click(Sender: TObject);
begin
x:=1;
while x=stringgrid1.rowcount do
  begin
    dodajl(StringGrid1.Cells[0, x],StringGrid1.Cells[1, x],StringGrid1.Cells[2, x],StringGrid1.Cells[3, x]);
    x:=x+1;
  end;
end;
(..)
{*******************LISTA DO STRINGGRID*******************}
procedure TForm2.Button8Click(Sender: TObject);
var nowy,tmp: PElement;
begin
x:=1;
tmp:=p;
  repeat
    begin
    stringgrid1.rowcount:=stringgrid1.rowcount+1;
    StringGrid1.Cells[0, x]:=tmp^.Nazwa;
    StringGrid1.Cells[1, x]:=tmp^.Cena;
    StringGrid1.Cells[2, x]:=tmp^.Gatunek;
    StringGrid1.Cells[3, x]:=tmp^.Platforma;
    {nowy^.Nazwa := naz;
    nowy^.Cena := cen;
    nowy^.Gatunek := gat;
    nowy^.Platforma :=pla; }
    tmp := tmp^.next;
    x:=x+1;
    end;
  until nowy=nil;
end;

{*******************PROCEDURY STARTOWE*******************}
procedure TForm2.FormCreate(Sender: TObject);
begin
     (..)
     start;
end;

To moja pierwsza przygoda z listami, dlatego ie mam pojęcia gdzie zrobiłem błąd. Korzystałem z wielu poradników i wydawało mi się że kod jest ok.

1

A kiedy ta pętla ma się skończyć ?

0

Głupi błąd, faktycznie. Pogrzebałem trochę w pętlach i teraz śmiga. Dzięki. Teraz czas na sortowanie ;p Zabieram się do pracy.
EDIT:
Kolejny problem, mianowicie gdy wyłączę program, to okienko się zamyka, ale program dalej jest uruchomiony w procesach.
Próbowałem zrobić mutexa, który nie pozwala otwierać go ponownie i działa, choć nie do końca. Mianowicie nie uruchamia się kolejny program (okno), ale w procesach niestety pojawia się kolejna kopia programu.
EDIT2:
To raczej nie jest wina ani mutexa, ani listy, ponieważ jak wykasowałem mutexa i nie stworzyłem listy, to problem był nadal.
EDIT3:
Znalazłem winowajce - ShareMem. Jak by ktoś miał podobny problem to wykasowanie tego z uses mi pomogło.

1 użytkowników online, w tym zalogowanych: 0, gości: 1