Lazarus 3.2 (2024.02.28.)
Letöltés

  • Oldal:
  • 1

TÉMA:

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 19:43 #451

  • dfeher
  • dfeher profilkép Témaindító
  • Moderátor
  • Moderátor
  • Hozzászólások: 26
  • Köszönetek: 0
Igen, már én is megtaláltam, mert nem hagyott nyugodni a dolog. :) Szerencsére nem kell olyan sok függvény címét tárolnom, úgyhogy megoldottam egy dinamikus tömbbel, de minden esetre egy kicsit azért úgy érzem paradoxon, ahogy ez meg van oldva. Talán egyszer majd továbbfejlesztik ezt a funkciót.

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 18:47 #450

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 506
  • Köszönetek: 86
Nézd mit találtam a Programmer's Guide -ban!

A metódusok esetén a procedurális típus két pointerrel van tárolva.
Az első a metódus belépési pontja a másik a hozzá tartozó "self",
vagyis a tartalmazó objektum címe.

Ez nyolc bájt, a mezei Pointer tipus pedig csak négy. Ezért nem lehet typecast-olni őket.

Esetleg ezzel:
KettoPointer=array[0..1]of Pointer;
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 3.0 -- FPC 3.2-- GNU/Linux 5.15.0 x86_64

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 16:18 #449

  • dfeher
  • dfeher profilkép Témaindító
  • Moderátor
  • Moderátor
  • Hozzászólások: 26
  • Köszönetek: 0
Akkor meg az lesz a nyűgje, hogy a pointer nem cast-olható TProc-ra (ami ugye ELVILEG nem pointer típus). :)

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 16:03 #448

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 506
  • Köszönetek: 86
Igazad van...

Újratöprengve:
Self.ProcList.Add(AProc); //és így nem a változó címét (a stack-ban) hanem annak értékét adja a listához
 
for i:=0 to (Self.ProcList.Count - 1) do TProcVar(Self.ProcList.Items[i])();
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 3.0 -- FPC 3.2-- GNU/Linux 5.15.0 x86_64

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 15:58 #447

  • dfeher
  • dfeher profilkép Témaindító
  • Moderátor
  • Moderátor
  • Hozzászólások: 26
  • Köszönetek: 0
Köszi a gyors választ, de: :)

Self.ProcList.Items(); nem működhet, mivel a láncolt lista osztály elemére való hivatkozás pointer-t ad vissza, és nem procedurális változót, ezért cast-olni kell feltétlenül. A te példádban, mint listát használod a tömböt, nekem viszont valódi láncolt listára lenne szükségem. Tömbbel egyébként nekem is működik az ügy, de a láncolt listával sokkal egyszerűbb lenne az elemeket kezelni.

Válasz:Objektum procedurális változója láncolt listában 2010 jan. 25 08:55 #446

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 506
  • Köszönetek: 86
Te írtad:
for i:=0 to (Self.ProcList.Count - 1) do 
  TProcVar(Self.ProcList.Items[i]^)();

Ezzel nem a mutatott címen kezdődő eljárást hívod, hanem onnan veszed az eljárás címét. Tehát az ott található eljárás első négy bájtját (ami gépi kódú utasítás) úgy használod mintha az az eljárásra mutató pointer lenne. Ráadásul közbeszólhat az operációs rendszer is hogy kódterületről nem olvashatsz adatot. Szerintem a következő módon próbáld hívni a tárolt rutint:
for i:=0 to (Self.ProcList.Count - 1) do
  Self.ProcList.Items[i]();

Mivel az alábbi hibátlanul működik:
type
  TProc=procedure;//a procedurális tipus meghatározása
 
var
  ProcVar:TProc; //ez veszi fel a procedura címét
  List:array[0..7]of TProc; //a procedurák címeinek listája
 
procedure TheProc; //ennek a címét kell a listába tenni
begin
  WriteLn('Hello Cruel World!'); //ezt fogja kiírni ha minden jól megy
end;
 
begin
  //List[0]:=@TheProc; // :)
  ProcVar:=@TheProc; //a procedure címének változóba helyezése
  List[0]:=ProcVar; //a változó értékének listába helyezése
  List[0]; //a procedure meghívása így történik
end.
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 3.0 -- FPC 3.2-- GNU/Linux 5.15.0 x86_64

Objektum procedurális változója láncolt listában 2010 jan. 24 15:45 #445

  • dfeher
  • dfeher profilkép Témaindító
  • Moderátor
  • Moderátor
  • Hozzászólások: 26
  • Köszönetek: 0
Sziasztok!

Egy kis problémám támadt a procedurális változókkal kapcsolatban. A példa:
{$mode objfpc}
 
type TProcVar = procedure() of object;
 
type Class1 = class
 
  ...
  ProcList: TList;
 
  constructor Create(AProc: TProcVar);
  procedure ExecuteAll;
 
  ...
end;
 
constructor Class1.Create(AProc: TProcVar);
begin
  Self.ProcList := TList.Create;
 
  { A gondok valószínűleg itt kezdődnek, mivel a listába
pointert kéne adni, de az AProc már pointer tulajdonképpen,
mivel a konstruktort így hívom meg:
 
Class1.Create(@SomeProc);
 }
 
  Self.ProcList.Add(@AProc);   { Ezért @AProc = @@SomeProc ?! }
end;
 
procedure Class1.ExecuteAll;
var
  i: Integer;
begin
  { Ez SIGSEGV-et generál: }
 
  for i:=0 to (Self.ProcList.Count - 1) do
    TProcVar(Self.ProcList.Items[i]^)();
end;

Tehát a kérdésem, hogy hogy lehetne egy osztály láncolt
listáját használni más osztályok függvényeinek a címének
tárolására?

Köszönöm a segítséget!

  • Oldal:
  • 1