Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Array[0..0] Speicherreservieren (https://www.delphipraxis.net/154335-array%5B0-0%5D-speicherreservieren.html)

Alter Mann 7. Sep 2010 09:33

Delphi-Version: 2009

Array[0..0] Speicherreservieren
 
Moin, Moin,

ich habe das 'kleine' Problem, dass ich ein innerhalb eines Records ein dynamisches Array habe, welches initialisiert sein muss, bevor ich es auf eine Funktion los lasse.
Doch wie mach ich das?
Delphi-Quellcode:
...
type
  DLI = record
    Count : DWORD;
    SIG  : DWORD;
    PE   : Array[0..0] of PI;
  end;

...
var
  D : DLI;
begin
  SetLength(D.PE, 15 * SizeOf(PI));  // Inkompatible Typen
  D.PE := AllocMem(15 * SizeOf(PI)); // - " - Array und Pointer (Das ist klar)
  @D.PE := AllocMem(15 * SizeOf(PI)); // der linken Seite kann nichts zugewiesen werden
end;
Ich kann die Struktur des Record nicht ändern. Gibt es noch eine andere Möglichkeit?

Danke

Neutral General 7. Sep 2010 09:37

AW: Array[0..0] Speicherreservieren
 
Hallo,

Also das Array ist schon initialisiert. (Hat die Größe von SizeOf(PI))
Bist du dir sicher, dass es nicht vllt. ein Pointer auf so ein Array[0..0] sein soll?
Weil dann sähe das ganze schon wieder anders aus.

Delphi-Quellcode:
type
  TPIArr = Array[0..0] of PI;
  PPIArr = ^TPIArr;

  DLI = record
    Count: DWORD;
    SIG: DWORD;
    PE: PPIArr;
  end;

var D: DLI;
begin
  GetMem(D.PE,15*SizeOf(PI));
end;

Alter Mann 7. Sep 2010 09:44

AW: Array[0..0] Speicherreservieren
 
Hallo,

die Idee mit GetMem ist nicht schlecht:?, nur, ich kann den Record nicht ändern!
"Fehlermeldung: Inkompatible Typen":(

Neutral General 7. Sep 2010 09:46

AW: Array[0..0] Speicherreservieren
 
Also wenn du das Rekord nicht ändern kannst und ich nicht gerade aufm Schlauch stehe, dann glaube ich nicht, dass du da irgendwas machen kannst...

PS: Ein GetMem mit einem Nicht-Pointer-Typ funktioniert natürlich nicht (Inkompatible Typen)

mkinzler 7. Sep 2010 09:50

AW: Array[0..0] Speicherreservieren
 
Da der Compiler ja den Typ PI kennen sollte, sollte

Delphi-Quellcode:
SetLength(D.PE, 15);
reichen

Neutral General 7. Sep 2010 09:54

AW: Array[0..0] Speicherreservieren
 
Zitat:

Zitat von mkinzler (Beitrag 1047953)
Da der Compiler ja den Typ PI kennen sollte, sollte

Delphi-Quellcode:
SetLength(D.PE, 15);
reichen

PE ist aber kein dynamisches Array. Das wird also mit SetLength nicht funktionieren.
Ich bin immernoch der Meinung, dass es nicht geht.

Alter Mann 7. Sep 2010 09:55

AW: Array[0..0] Speicherreservieren
 
Zitat:

ich nicht gerade aufm Schlauch stehe
Das wollen wir doch mal nicht hoffen:wink:

Hintergrund ist IOCTL_DISK_GET_DRIVE_LAYOUT vielleicht fällt da der Groschen?

Das, das ein Thema für sich ist, ist mir klar aber es muss doch eine Alternative zu diesem
C-Code geben:
Code:
DWORD junk;
BOOL bResult;

DWORD nPartitions = 16;
DWORD nBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + nPartitions * sizeof(PARTITION_INFORMATION);

DRIVE_LAYOUT_INFORMATION* pDLI =
(DRIVE_LAYOUT_INFORMATION*)malloc(sizeof(DRIVE_LAYOUT_INFORMATION) + nPartitions * sizeof(PARTITION_INFORMATION)); // <- wie in Delphi?

bResult = DeviceIoControl(hDevice,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
pDLI,
nBufferSize,
&junk,
NULL);
Wie geschrieben es geht hier nicht um IOCTL_DISK_GET_DRIVE_LAYOUT sondern um die Speicherreservierung.

himitsu 7. Sep 2010 09:57

AW: Array[0..0] Speicherreservieren
 
Ein Array[0..0] ist ein statisches Array (ohne Bereichsprüfung) und über SetLength kann man nur dynamische Arrays behandeln.

Wenn, dann könnte man also nur den Speicher für den ganzen Record reservieren.
Delphi-Quellcode:
type PDLI = ^DLI;

var X: PDLI;

X := GetMemory(SizeOf(DLI) + (PE_Count - 1) * SizeOf(PI));
Ich hatte es mir allerdings einfach gemacht und it diese Records/Arrays selbstdefiniert und die Arrays mit einer maximal zu erwartenden Größe deklariert, als ich das letzte Mal mit sowas arbeitete.

[edit]
oder so :oops:

Neutral General 7. Sep 2010 09:58

AW: Array[0..0] Speicherreservieren
 
So:

Delphi-Quellcode:
var D: ^DLI;
begin
  GetMem(D,SizeOf(DLI) + 15*SizeOf(PI));
end;
@himitsu (über mir): GetMem ist eine Procedure mit 2 Parametern. Du meinst wahrscheinlich GetMemory :stupid:

SirThornberry 7. Sep 2010 10:02

AW: Array[0..0] Speicherreservieren
 
Warum kannst du den RecordTyp nicht ändern? Wer zwingt dich beim Aufruf die nicht funktionierende Variante zu verwenden? Wer hindert dich daran das Array einfach groß genug zu definieren?

mkinzler 7. Sep 2010 10:06

AW: Array[0..0] Speicherreservieren
 
Oder halt einen dynamischen Array zu verwenden

Neutral General 7. Sep 2010 10:07

AW: Array[0..0] Speicherreservieren
 
Zitat:

Zitat von mkinzler (Beitrag 1047963)
Oder halt einen dynamischen Array zu verwenden

Damit wird die API nicht klarkommen, weil dynamische Arrays anders aufgebaut sind.
(Sind ja nur Pointer und hier werden ja direkt im Record mehrere hintereinanderliegende Strukturen erwartet)

himitsu 7. Sep 2010 10:07

AW: Array[0..0] Speicherreservieren
 
Diese nichtfunktionierende Variante ist ein Versuch einer direkten Übersetzung der C-Header von Microsoft.

Dort kann man statische Arrays mit [0]-Länge deklarieren.
(leider kennt Delphi sowas nicht, so daß man sich über den Sonderfall von [0..0] das Array mit einem Feld und ohne Bereichsprüfung zu nutzen)
In den C-Vorlangen wird dann ebenfalls so gearbeitet, wie in meinem Beispiel.

Aber wie gesagt, ich mochte diese Arrays auch nicht und hab das mit selbstdeklariert, womit ich mir dan die Resourcenschutzblöcke und einen Großteil der Speicherverwaltung erspart hab.
(man darf auch mal Faul sein :angel2: )

[edit]
OK, hier gibt es sogar mal ein [1]-Array im Original-Header
http://msdn.microsoft.com/en-us/library/aa364001.aspx
(es ist also eine fast 1:1-Übersetzung)

Alter Mann 7. Sep 2010 10:13

AW: Array[0..0] Speicherreservieren
 
Hallo

und danke an alle, damit geht es:
Delphi-Quellcode:
var D: ^DLI;
begin
  GetMem(D,SizeOf(DLI) + 15*SizeOf(PI));
end;
Die Thematik IOCTL_DISK_GET_DRIVE_LAYOUT kommt gesondert.

Danke bis zum 17.

Alter Mann 7. Sep 2010 10:16

AW: Array[0..0] Speicherreservieren
 
@himitsu

genau, nur das ich DRIVE_LAYOUT_INFORMATION_EX nicht verwenden darf; W2K lässt grüßen.

generic 7. Sep 2010 13:21

AW: Array[0..0] Speicherreservieren
 
Hast du mal probiert das array als
Delphi-Quellcode:
  DLI = record
    Count : DWORD;
    SIG : DWORD;
    PE : Array of PI;
  end;
zu definieren. Dann sollte auch SetLength funktionieren.

SirThornberry 7. Sep 2010 13:26

AW: Array[0..0] Speicherreservieren
 
@generic: Dann wäre es nicht kompatibel zu dem erwarteten C-Record. Es würde sogar mächtig krachen weil dann die interna des dynamischen Arrays überschrieben werden.
Denn das dynamische Arry an dieser Stelle stellt an einer anderen Stelle den Speicher zur Verfügung und nicht an der Stelle im Record.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:07 Uhr.

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