Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Array: C vs Delphi (https://www.delphipraxis.net/144221-array-c-vs-delphi.html)

Mithrandir 2. Dez 2009 19:47


Array: C vs Delphi
 
Hi ihr,

ich lerne in der FH C (nicht C++) und bin gerade dabei, ein Programm zu Lernzwecken zu übersetzen. Prinzipiell ist mir klar was das Programm macht, aber mit den internen Strukturen der beiden Compiler bin ich grad nicht so firm. Es geht um Folgendes:

Code:
unsigned char *data_buf;
data_buf ist ein Zeiger vom Typ "unsigned char". Das entspräche:

Delphi-Quellcode:
fDataBuffer : PByte;
Nu' is es aber so, dass man auch Felder in C so darstellen kann. Und dann wäre das Äquivalent in Delphi:

Delphi-Quellcode:
fDataBuffer : Array of Byte;
Ich vermute fast, dass es sich um ein Feld handelt, denn im Verlauf des Quelltextes taucht dieses Konstrukt auf:

Code:
ZeroMemory(data_buf, 28);
Somit wird ab der Adresse "data_buf" ein Block von 28 Byte mit Nullen aufgefüllt. Habe ich das so richtig interpretiert? Und wenn ja, brauche ich dann bei Delphi für das dynamische Array SetLength, oder übernimmt das ZeroMemory? Oder kann ich gar mit der allerersten Deklaration als PByte arbeiten?

P.S.: Bei data_buf handelt es sich um einen Parameter für eine Struktur einer Windows API-Funktion, Delphi-Referenz durchsuchenDeviceIOControl

himitsu 2. Dez 2009 20:00

Re: Array: C vs Delphi
 
ZeroMemory übernimmt nichts ... das weiß nichtmal, daß es ein Array ist

besser
Delphi-Quellcode:
ZeroMemory(@data_buf[0], 28);
oder du arbeitest mit einem statischen Array

Delphi-Quellcode:
TDataBuffer = Array[0..27] of Byte;
PDataBuffer = TDataBuffer;

fDataBuffer : PDataBuffer;
oder direkt
Delphi-Quellcode:
fDataBuffer : TDataBuffer;
und dann überall das @ nicht vergessen

SirThornberry 2. Dez 2009 20:05

Re: Array: C vs Delphi
 
Code:
unsigned char *data_buf
das ist ein Pointer auf einen unsigned char.
Arrays werden in C als Pointer übergeben. Wenn man also ein Array von unsigned char hat wird nur ein Pointer auf das erste Element übergeben.

folgendes ist also identisch:
Code:
void yourfunction(unsigned char data[]);
void yourfunction(unsigned char *data);
innerhalb der Funktion kann man in beiden Fällen mit
Code:
data[i]
auf ein Element zugreifen. Es ist also reine Geschmackssache wie man die Function declariert.

Mithrandir 2. Dez 2009 20:09

Re: Array: C vs Delphi
 
Zitat:

Zitat von himitsu
oder du arbeitest mit einem statischen Array

Geht nicht, da es in diversen anderen Funktionen andere Größen und Werte annehmen kann. Daraus schließe ich jetzt, dass Delphi nicht ohne SetLength kann, oder?

@SirThornberry:
Danke, das wusste ich. :) Mir gings nur darum, ob Delphi und C Arrays Grundverschieden behandeln. Bin mir da nämlich grad nicht so sicher... :gruebel: Und nur, weil der Compiler was mit sich machen lässt, heißt das ja nicht, dass es richtig ist... :stupid:

himitsu 2. Dez 2009 20:21

Re: Array: C vs Delphi
 
eine fast korrekte Übersezung wäre
Delphi-Quellcode:
TDataBuffer = Array[0..0] of Byte;
PDataBuffer = TDataBuffer;

fDataBuffer : PDataBuffer;
hier müßte man dann per GetMem genügend Speicher reservieren und könnte es wie ein Array ansprechen

0..0 ist ohne Indexprüfung

aber irgendwo müßte doch in C die größe des "Arrays" definiert werden?


Das dynamische Delphi-Array hat vor den Arraydaten noch Infos die Größe und Referenzzähler,
also ganz kompatibel sind C- und Delphi-Array nicht.

Mithrandir 2. Dez 2009 20:27

Re: Array: C vs Delphi
 
Zitat:

Zitat von himitsu
aber irgendwo müßte doch in C die größe des "Arrays" definiert werden?

ARGH... :wall:

Gefunden:

Code:
data_buf=(unsigned char *)malloc(65536);
:stupid:

data_buf ist in dem Beispiel eine globale Variable, der QT hat über 1200 Zeilen und die Main-Funktion ist natürlich ganz am Ende... :roll:

Also wäre dein letzter Vorschlag das "Fast" - Äquivalent dazu, oder?

Medium 2. Dez 2009 21:45

Re: Array: C vs Delphi
 
Dat tolle is, unter C weisst du nicht wie lang ein Array ist, wenn du es dir nicht selbst merkst. Da scheint einfach mal ein "genügend" großes alloziiert zu werden (64k, yay), so dass was auch immer da mal rein schreiben wird da genug Platz für hat - WinAPI Funktionen geben oft irgendwie die Anzahl tatsächlich geschriebener Bytes zurück. Dass da dann 28 von genullt werden... tjoa, scheint wohl irgendwozu gebraucht zu werden :stupid:

Die vernünftige Delphi-Like Übersetzung wäre dann
Delphi-Quellcode:
var
  DataBuf: {packed} array of Byte; // packed wenn alignment auf > 1 Byte steht
begin
  SetLength(DataBuf, 65536); // entspricht quasi dem malloc()
  ZeroMemory(@DataBuf[0], 28);
Wobei letztlich fraglich ist, ob es sich lohnt 64k einfach mal auf Verdacht zu kapern. Sinniger erscheint mir hier nach Bedarf die Länge zu sezten.

Arrays sind intern bei beiden Sprachen fast gleich. Bei Delphi sitzt eben vorm 0-ten Element noch ein Längen-DWord, weshalb man bei C-Array erwartenden Funktionen explizit einen Pointer auf das 0-te Element übergeben sollte. In den meisten Fällen erledigt das einfaches hinschreiben ohne @ und [0] auch, da hängt's dann davon ab wie die Funktion importiert wurde. Der Regelfall ist, dass C-Pointer einfach als typenlose Pointer übersetzt werden, wo ein @ obligatorisch wird. Möglich wäre aber wohl auch ein harter Cast "Pointer(DataBuf)".
Man muss eben nur ggf. auf's Alignment achten, was wenn nicht anders dokumentiert "packed" entsprechen sollte.

Mithrandir 2. Dez 2009 21:56

Re: Array: C vs Delphi
 
Zitat:

Zitat von Medium
Dat tolle is, unter C weisst du nicht wie lang ein Array ist, wenn du es dir nicht selbst merkst.

Ja, das hab ich auch schon gemerkt. :stupid: Unser Prof lässt uns gerade wild mit Pointern herumschießen...

Zitat:

Zitat von Medium
Da scheint einfach mal ein "genügend" großes alloziiert zu werden (64k, yay), so dass was auch immer da mal rein schreiben wird da genug Platz für hat - WinAPI Funktionen geben oft irgendwie die Anzahl tatsächlich geschriebener Bytes zurück. Dass da dann 28 von genullt werden... tjoa, scheint wohl irgendwozu gebraucht zu werden :stupid:

Ja, die 64k werden tatsächlich nachher als Puffer genutzt. Die Struktur, die in diesem Beispiel das mit 28 Byte genullte Feld per Pointer bekommt, bekommt auch die Länge mitgeteilt. Für die Struktur sieht das also so aus, als hätte das Feld, was hinter dem Pointer steckt, nur 28 Elemente. Je mehr ich drüber nachdenke, desto "unschöner" finde ich die Herangehensweise... :gruebel:

Danke für Ausführungen. :thumb:

generic 2. Dez 2009 22:09

Re: Array: C vs Delphi
 
Zitat:

Zitat von Daniel G
Code:
unsigned char *data_buf;
data_buf ist ein Zeiger vom Typ "unsigned char". Das entspräche:

Delphi-Quellcode:
fDataBuffer : PByte;

Du kannst das auch in PAnsiChar übersetzen.

Delphi-Quellcode:
var
  fDataBuffer : PAnsiChar;

  fDataBuffer:=Alloc(65536);
  // Natürlich nicht vergessen den Speicher wieder freigeben

  fDataBuffer^[123]:='C';


Für ein Array halte ich deine Beschreibung nicht.
Sieht eher nach einen String aus.

p80286 3. Dez 2009 13:04

Re: Array: C vs Delphi
 
Zitat:

Delphi-Quellcode:
var
  DataBuf: {packed} array of Byte; // packed wenn alignment auf > 1 Byte steht

Wenn ich meiner D7-Hilfe glauben darf, ist das "packed" überflüssig/Blödsinn/falsch da "packed" nur bei Records (und Objekten) eine Auswirkung hat.
Arrays liegen immer Byte an Byte.

Oder hab ich da etwas falsch verstanden?

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:58 Uhr.
Seite 1 von 2  1 2      

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