Autor Beitrag
icho2099
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 101
Erhaltene Danke: 12

WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005, FPC
BeitragVerfasst: Do 16.07.20 17:08 
Hallo, ich hoffe es kann mir jemand auf die Sprünge helfen.
Ich habe die tgPuttyLib (sftp Klasse) und finde darin eine Struktur, die ich zusammen mit dem Beispiel nicht verstehe.
Zunächst die Deklaration:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
type fxp_attrs=record
                 flags:UInt32;
                 size: UInt64;
                 uid,gid,
                 permissions,
                 atime,mtime:UInt32;
               end;
     Pfxp_attrs=^fxp_attrs;

     fxp_name=record
                filename,longname:PAnsiChar;    //zwei Strings 
                attrs            :fxp_attrs;    //ein Record für Attribute
              end;
     Pfxp_name=^fxp_name;

     fxp_names=record
                 nnames:Integer;                 //number of names ??? count ?
                 names:Pfxp_name;                //pointer auf record fxp_name
               end;
     Pfxp_names=^fxp_names;


Dann die Frage:
In einem Beispiel wird das so verwendet:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function TTester.ListingCallback(const names:Pfxp_names):Boolean;
var i:Integer;
begin
  for i:=0 to names^.nnames-1 do
    WriteLn(names^.names[i].filename:40,'  ',names^.names[i].attrs.size:10);
  Result:=true;
  end;


Der Teil names.names[i] wird vom Compiler, meiner Meinung nach zu Recht, angemeckert, weil in der
Deklaration gibt es kein Array das man indizieren könnte. "Error: Array type required"

Andererseits enthält die Deklaration mit nnames ja ein
Feld welches die Anzahl der Records angeben soll(te), mit names:Pfxp_name aber nur einen Pointer auf ein fxp_name Record.
Und das enthält auch keine weiteren Pointer die eine Liste bilden könnten.

Ohne den Index liefert mir names.names.filename einen Dateinamen, der auch stimmt. Aber nur den einen obwohl nnames 4 liefert.
Wie names zusammengestöpselt wird kann ich nicht sagen, das verbirgt sich in der tgputtylib.dll
Gibt es da in Delphi vielleicht eine gewisse Magie, die names indizierbar macht ohne das zu deklarieren? Und wenn ja, wie
bringt man das dann dem Larzarus/fpc bei?
Habe da einen Knoten im Hirn, komme nicht drauf wie das richtig funktionieren soll. Wäre für Hilfe und Tips dankbar.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4791
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 16.07.20 18:47 
Das ist, wie in C, ein Zeiger auf einen dynamisch allozierten Bereich (Array), d.h. die einzelnen record-Elemente liegen hintereinander im Speicher und können über den Index angesprochen werden (und dafür auch zusätzlich die Variable nnames, um die Größe zu speichern bzw. den Wertebereich der Indizes zu wissen).

Der Speicher wird dann wohl mittels GetMem angelegt worden sein.

Da du schreibst, daß Lazarus (bzw. genauer 'Free Pascal') das nicht unterstützt, wirst du wohl dann die Syntax für ein dynamisches Array dort benutzen müssen.

Edit: Für Delphi muß man wohl {$POINTERMATH ON} aktivieren, s. Pointer Math (Delphi). Dies sollte auch bei Free Pascal so funktionieren: The POINTERARITHMETICS mode switch has been replaced with the POINTERMATH directive.

Für diesen Beitrag haben gedankt: icho2099
icho2099 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 101
Erhaltene Danke: 12

WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005, FPC
BeitragVerfasst: Fr 17.07.20 10:26 
Besten Dank user profile iconTh69

{$POINTERMATH ON} ist die Lösung.