Autor Beitrag
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: So 19.01.03 14:23 
Hallo liebe Experten,

ich kenne mich eigentlich nicht mit C++ aus, aber ich habe da mal einen sourcecode gelesen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
typedef struct
{
    WORD           idReserved;
    WORD           idType;
    WORD           idCount;
    ICONDIRENTRY   idEntries[1];of 'em)
} ICONDIR;


idEntries ist ein dynamischer Array. Wenn man die Struktur (den Record) mit einem Stream einliest, und idEntries 3 Elemente hat, werden auch 3 Elemente gelesen.

In Delphiy müsste das dann so aussehen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
type
 IconDir = record
  idReserved: DWord;
  idType: DWord;
  idCount: DWord;
  idEntries: Array Of IcondirEntry;
 end;


OK, aber wenn ich das mit 'nem Stream einlese, wird der Array nicht eingelesen (da es sich hier ja nur um Pointer handelt). Aber Dynamische Arrays lasesn sich eben nur mit Pointern realisieren (Ich will keinen Statischen Array).

Jetzt müsste ich die ersten 3 Elemente als Record einlesen, und dann jedes Element des Arrays manuell. Aber gibt es auch einen anderen Weg, oder ist das eine Sache, in der uns C++ vorraus ist?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: So 19.01.03 18:21 
Wie würdest du denn die obige Structur in C++ einlesen? Das geht auch nur über vorheriges einlesen von Count, denn das Array besitzt im Grunde nur 1 Element.

_________________
Ist Zeit wirklich Geld?
Andreas Pfau Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: So 19.01.03 20:15 
Äh, sorry, schreiben meine ich :oops:

Mit C++ kann man die Länge des Arrays festlegen, und dann werden so viele Elemente geschreiben, wie der Array hat. Mit Delphi wird nur der Zeiger geschreiben (also 4 Byte), und damit kann man nix anfangen.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: So 19.01.03 21:24 
Würde sich damit nicht das Array im Stream statisch?
Ich würde zuerst das Record schreiben, und dann für jeden Eintrag im Array (for i := 0 to High(array) -1 usw) hinten dranhängen. Dsa geht aber nur so llange, wie nur ein Record im Stream ist. Für den Fall, daß da mehrere im Stream sind, würde ich die momentane Länge des Array speichern (als Integer, also immer 4 Byte) und dann dannach den Inhalt des Arrays. Das auslesen geht dann genauso. Erst das Record auslesen, dann schauen, wie lang das Array ist (nächsten 4 Byte auslesen, da steht's drin) und dann die eben ausgelesene Anzahl an Bytes zurückauslesen und in das Array zurückspeichern.
Dann weißt du automatisch, daß hinter dem Array (also nach der Anzahl an Bytes, die du nach dem Record ausgelesen hast) das nächste Record anfängt, wieder gefolgt von einer Array-Länge und dem Array-Inhalt, wieder gefolgt von einem Record usw.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Andreas Pfau Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: So 19.01.03 22:08 
Ja, schon kalr, so mache ich das ja auch immer. Ich wollte nur wissen, ob das auch so geht wie in C++, also Länge festlegen und den gesamten Record auf einmal schreiben, und nicht Element für Element.
Andreas Pfau Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: So 19.01.03 22:58 
Juhu, ich habe es geschafft. Ich habe grade einen code zum Erstellen einer Palette geschreiben, da fiel mir auf, dass das ja genau das ist, was ich suche. So gehts:

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
type
 TTestRecord = packed record
  S: Integer;
  A: Array[0..0] Of Char;
 end;

procedure TMain.Button1Click(Sender: TObject);
var
  T: ^TTestRecord;
  S: TFileStream;
  I: Integer;
begin
  GetMem(T, SizeOf(TTestRecord) + 4 * SizeOf(Char));
  T.S := 5;
  I := 0; T.A[I] := 'H';
  I := 1; T.A[I] := 'e';
  I := 2; T.A[I] := 'l';
  I := 3; T.A[I] := 'l';
  I := 4; T.A[I] := 'o';

  S := TFileStream.Create('Test.hex', fmCreate);
  S.Write(T^, SizeOf(TTestRecord) + 4 * SizeOf(Char));
  S.Free;
  FreeMem(T);
end;

procedure TMain.Button1Click(Sender: TObject);
var
  T: ^TTestRecord;
  S: TFileStream;
  I, L: Integer;
  E: String;
begin
  S := TFileStream.Create('Test.hex', fmOpenRead);

  GetMem(T, SizeOf(TTestRecord));
  S.Read(T^, SizeOf(Integer));
  L := T.S;
  GetMem(T, SizeOf(TTestRecord) + (L - 1) * SizeOf(Char));

  S.Read(T^.A, SizeOf(Char) * L);

  S.Free;

  E := '';
  For I := 0 To L - 1 Do
   E := E + T.A[I];

  ShowMessage(E);
 
  FreeMem(T);
end;


Funktioniert aber leider nur mit einem Array, und der muss am Ende sein (weil ja sonst die Absolute Adresse der folgenden Variablen nicht mehr stimmen würde).