Autor Beitrag
Barzi
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 29.12.08 23:59 
Hallo Delphianer!

Ich bin im Moment dabei eine Unit zu schreiben, die häufig benötigte Prozeduren und Funktionen enthält. Das ist weiter nichts besonderes, allerdings scheitere ich bei der Übergabe von Arrays an diese Unit.

Ich habe irgendwo ein Array wie folgt deklariert
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type TMyRecord = record  // ein Record
  MyContent: String[255]; // mit beliebigen Inhalt
end;

TMyArray = array of TMyRecord;


Nun soll die Prozedur in meiner Unit auf das Array zugreifen und es verändern können
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure MyProcedure(a:???);
begin
  SetLength(a,length(a)+1);
end;


Und genau da -> ??? liegt das Problem. Ich habe mir etwas zu offenen und untypisierten Parametern durchgelesen, allerdings sehe ich nirgendswo eine Möglichkeit die Prozedur so zu gestalten, dass ich beliebige Arrays eines Records übergeben kann, wie man es z.B. bei SetLength tun kann.

Meine Frage also:
Wie kann man eine so freie Parameter-Übergabe wie bei SetLength realisieren?
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Di 30.12.08 00:02 
ausblenden Delphi-Quelltext
1:
procedure MyProcedure(var a: TMyArray);					

_________________
PROGRAMMER: A device for converting coffee into software.
Barzi
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.12.08 00:08 
Ich fürchte du hast mich missverstanden.

Ich möchte jedes beliebige Array eines Records übergeben können.
Wenn ich also in einem anderen Programm mein Record so deklariere
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type TMySecondRecord = record  // ein anderes Record
  DifferentContent: String[255]; // mit anderem Inhalt
end;

TMySecondArray = array of TMySecondRecord;

soll es trotzdem noch möglich sein TMySecondArray an die Prozedur zu übergeben.

Trotzdem danke für deine schnelle Antwort
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Di 30.12.08 00:11 
Achso, du meinst, eine Procedure, die mit allen weltweit in Delphi geschriebenen Arrays klarkommt?
Öhh.. wüsst ich jetzt nicht, ob / wie das geht.

_________________
PROGRAMMER: A device for converting coffee into software.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 30.12.08 00:15 
Das nennt sich "variant open array parameters". Mehr dazu findest du hier unter "Array of const":
rvelthuis.de/article...rticles-openarr.html

Das wird beispielsweise bei Format benutzt.

Beispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function test(a: array of const): Integer;
begin
  Result := Length(a);
end;
Barzi
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.12.08 00:39 
Ah, vielen Dank!
Ich werde es morgen mal ausprobieren :D

[OffTopic]
Hatte der Nussknacker-Wettbewerb 2008 was mit Arrays zu tun?! :P
[/OffTopic]
Barzi
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.12.08 15:45 
Also das mit den "variant open array parameters" funktioniert, allerdings mit einer Einschränkung bei SetLength. Hier mein Code zum speichern und laden eines Arrays:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure SaveArrayToFile(const FileName: String; a: array of const; TypeSize: Integer);
  var f: TFileStream;
      i: integer;
begin
  f := TFileStream.Create(FileName,fmCreate);
  for i := 0 to high(a) do
    f.write(a[i],TypeSize);
  f.free;
end;

procedure LoadArrayFromFile(const FileName: String; a: array of const; TypeSize: Integer);
  var f: TFileStream;
      i: integer;
begin
  f := TFileStream.Create(FileName,fmOpenRead);
  SetLength(a,f.Size div TypeSize);
  for i:= 0 to High(a) do
    f.read(a[i],TypeSize);
  f.free;
end;


SaveArrayToFile funktioniert, aber bei LoadArrayFromFile gibt es für SetLength Inkompatible Typen als Compiler-Fehler. Eigentlich ist das auch nicht verwunderlich, denn SetLength ist ja wie folgt überladen deklariert:
ausblenden Delphi-Quelltext
1:
2:
procedure SetLength ( var StringToChange  : string; NewLength  : Integer ) ;
procedure SetLength ( var ArrayToChange : Array type; Dim1Length : Integer {;Dim2Length : Integer; ...} ) ;

Die erste Deklaration verstehe ich noch, aber ich weiß nicht was es mit der zweiten auf sich hat, insbesondere bei "var ArrayToChange : Array type;". Ist es denn überhaupt möglich SetLength bei Array of const zu verwenden?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 30.12.08 16:34 
Nein, das geht nicht, das steht aber auch in dem Link. Dort gibt es auch ein Beispiel mit TConstArray, was dann wohl eher das ist, was du braucht.

Intern ist ein array of const (wie dort ja auch steht) ja ein Array of TVarRec.

Wobei ein solches Vorgehen beim Speichern und Laden schon etwas seltsam ist, ich weiß nicht ob das (sinnvoll) klappt. :nixweiss:

// EDIT:
Eine Idee wäre, dass du dir ähnlich wie bei API Funktionen mit einem leeren übergebenen Array zuerst die Länge geben lässt, diese setzt, und dann erneut die Prozedur aufrufst. (Ich bin mir aber nicht so sicher, ob read und write überhaupt so funktionieren.)
Barzi
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.12.08 17:06 
Also ich denke dann ist mein Ansatz schon zum scheitern verurteilt und auch nicht ratsam, aber das Beispiel mit TVarRec werde ich mir jetzt mal anschauen, ich hatte es mit gar nicht mehr durchgelesen, weil ich so auf array of const fixiert war, sorry deswegen.

Aber die Frage ist ja mit array of const beantwortet und ich will nun auch nicht ein neues Thema in diesem Thread anfangen.

Also vielen Dank euch beiden, vielleicht eröffne ich demnächst nochmal ein Thema über praxistaugliche Speichermethoden. :wink: