Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi MMF und dynamische Arrays? (https://www.delphipraxis.net/68751-mmf-und-dynamische-arrays.html)

mumu 4. Mai 2006 19:40


MMF und dynamische Arrays?
 
ich benutze MMF zur Interprozesskommunikation.

Jetzt habe ich folgendes Problem:
Wenn mein MMF-Data Record ein dynamisches Array of string beinhaltet, dann funktioniert das ganze nicht.

array[1..10] of String[255]; // funktioniert
array of String[255]; // funktioniert nicht

ist das Normal? Wie kann ich das ggfs. irgendwie hinbekommen? Muss ich dann mein Array immer entsprechend groß wählen und somit eventuell sehr viel speicherplatz verschwenden.

gruß

himitsu 4. Mai 2006 20:05

Re: MMF und dynamische Arrays?
 
Das ist normal, denn Arrays und auch die Strings(intern auch Arrays) sind nur Pointer auf die entsprechenden Daten ... du müßtest also auch noch die Strngs und arrays mit in die MMF reinkopieren.

mumu 4. Mai 2006 20:20

Re: MMF und dynamische Arrays?
 
hmm und wie mach ich sowas?

also wenn ich das richtig verstanden hab, dann passiert folgendes:
array[1..10] of String[255]; erzeugt wahrscheinlich 10 hintereinanderliegende strings der länge 255
array of String[255]; erzeugt im endeffekt ein array of pointer auf strings der länge 255 und diese pointer sind im anderen prozess ungültig

himitsu 5. Mai 2006 11:43

Re: MMF und dynamische Arrays?
 
fast richtig ^^

Zitat:

array[1..10] of String[255]; erzeugt wahrscheinlich 10 hintereinanderliegende strings der länge 255
inclusive einem Längenbyte (da ja nicht unbedingt alle 255 Chars belegt sein müssen)

es entsteht also ein Record wie dieser:
länge1, char1.1, char1.2 ... char1.255, länge2, char2.1, char2.2 ... char2.255 ... char10.255

Zitat:

array of String[255]; erzeugt im endeffekt ein array of pointer auf strings der länge 255 und diese pointer sind im anderen prozess ungültig
erzeugbt 'nen Pointer mit einem array von x-aufeinanderfolgenden String[255]


und array of String erzeigt einen pointer auf ein Array mit x-aufeinanderfolgenden Pointer, welche auf Strings zeigen :mrgreen:


Das Array[1..10] of String[255] kannst du also ohne Problem in die MMF kopieren und da wieder rauskolen
Delphi-Quellcode:
CopyMem(@MyArray, MMF, SizeOf(MyArray));
Delphi-Quellcode:
CopyMem(MMF, @MyArray, SizeOf(MyArray));
Beim Array of String[255] mußt du den Inhalt (nicht den Pointer auf den Inhalt, darum die Referenz auf das erste Arrayelement - MyArray[0]) und die Länge des Arrays kopieren
Delphi-Quellcode:
i := Length(MyArray);
CopyMem(@i, MMF, 4);
CopyMem(@MyArray[0], MMF + 4, i * SizeOf(MyArray[0]));
Delphi-Quellcode:
CopyMem(MMF, @i, 4);
SetLength(MyArray, i);
CopyMem(MMF + 4, @MyArray[0], i * SizeOf(MyArray[0]));
PS: SizeOf(MyArray[0]) ist die größe eines Arrayelements ... entspricht also SizeOf(Typ) von Array of Typ

Beim Array of String könntest zu zwar auch das Array mit seiner Länge und jeden String speichern,
aber da das Array eh nur mit Pointer gefüllt ist, welche drüben geändert werden müßten,
macht es sich einfacher, wenn man nur die Stringinhalte mit ihrer Länge und deren Anzahl speichert,
also
anzahl(integer), Len(integer), Stringinhalt..., Len(integer), Stringinhalt..., Len(integer), ...

Delphi-Quellcode:
i := Length(MyArray);
CopyMem(@i, MMF, 4);
i3 := 4;
For i2 := 0 to i - 1 do Begin
  i4 := Length(MyArray[i2]);
  CopyMem(@i4, MMF + i3, 4);
  Inc(i3, 4);
  CopyMem(@MyArray[i2][1], MMF + i3, Length(MyArray[i2]));
  Inc(i3, Length(MyArray[i2]));
End;
und raus natürlich andersrum ^^

Die Beispiele ... erst in die MMF (was hier einfach mal als Pointer auf das erste Byte der MMF verwendet wurde) und dann wieder raus

[edit]
jupp, massig Fehler ._.


PS: so ein statisches Array[1..10] of String[255]; hat aber auch noch den Vorteil, daß man es auch die ganze Zeit in der MMF lassen kann.
Delphi-Quellcode:
Type TMyArray = Array[1..10] of String[255];
  PMyArray = ^TMyArray;

// und zum lesen/schreuben einfach
PMyArray(MMF)^[x]

// also z.B.
PMyArray(MMF)^[3] := S;
If PMyArray(MMF)^[4] = '123' Then
  S := PMyArray(MMF)^[5];
...

mumu 5. Mai 2006 11:53

Re: MMF und dynamische Arrays?
 
vielen vielen Dank himitsu !!! :thumb:

perfekt!


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz