Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi typedef struct aus C++ nach Delphi, LStrHandle LabView (https://www.delphipraxis.net/101625-typedef-struct-aus-c-nach-delphi-lstrhandle-labview.html)

sumara 16. Okt 2007 16:27


typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Hallöchen!

Ich hab grad ein ganz dringendes Problem mit einem LStrHandle von LabView.
Eine durch LabView generierte DLL soll in Delphi genutzt werden.
Eine Procedure verwendet den Parameter: LStrHandle * Parameter

Dieser ist wie folgt definiert:
Code:
typedef struct {
  int32  cnt;   /* number of bytes that follow */
  uChar str[1];   /* cnt bytes */
} LStr, *LStrPtr, **LStrHandle;
Leider bin ich in C++ überhaupt nicht fit! :cry:

Bisher hab ichs mit folgenden typen versucht:
Delphi-Quellcode:
type LStr=Array of Byte
Dieser Typ funktioniert bei einer anderen Procedur dieser DLL, die ebenfalls LStrHandle * Parameter als Übergabeparameter hat. (Nach Aussage des Entwicklers der C++ DLL heißt das aber noch lange nicht, dass diese Definition immer funktioniert)

Desweiteren hab ichs mit PChar und PAnsiChar probiert, bisher erfolglos.

Ich hoffe, dass mir jemand von Euch eine gute Delphi-Übersetzung für diesen Datentyp geben kann!!!

Vielen Dank für die Hilfe,

Susanne.

r2c2 16. Okt 2007 17:35

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Hallo,
also effektiv ist das nix anderes als eine C++-Implementierung von Dynamischen Strings ohne Referenzzählung. Also ähnlich wie die Delphi-Strings.

Meine Übersetzung sieht folgendermaßen aus:

Delphi-Quellcode:
type
  PByte = ^Byte;
  // direkt übersetzt
  LStr = packed record
    cnt: Integer;
    str: PByte;
  end
  LStrPtr = ^LStr;
  LStrHandle = ^^LStr;
Erklärung: In C++ sind ARAIK alle arrays implizit Pointer. Demnach ist uChar str[1] nix anderes als uChar * str;

//Nachttag:
Der Zugriff erfolgt dann über den Pointer:
Delphi-Quellcode:
  MyLStr.str[i] := #42;
mfg

Christian

OregonGhost 16. Okt 2007 18:57

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Witzig, kürzlich gab es ein ähnliches Problem hier in einem Thread von Tyrael.
Nein, char[1] ist nicht dasselbe wie char*. Der Unterschied: char* kann überall hinzeigen, char[1] ist hingegen ein 1 byte großes Array, das am Ende der Struktur liegt und dessen Größe vermutlich per realloc angepasst wird. PByte entspricht hier char*. Wichtig ist hierbei: sizeof(char*) == 4, sizeof(char[1]) == 1. Tyrael hat in seinem Thread array und array[0..0] probiert, beides ging leider nicht so sauber und ich kann für Delphi auch nicht sagen, wie man es macht, nur, wie man es nicht macht :)

Edit: Vielleicht funktioniert es ja genau wie in C? Einfach array[0..0] nehmen (was char[1] entspricht), dann den Speicherbereich, in dem die Struktur liegt, mit ReallocMem vergrößern und einfach auf Indizes > 0 zugreifen (Bereichsprüfung hierfür deaktivieren)?

Dax 16. Okt 2007 19:03

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Delphi-Quellcode:
type
  LStr = packed record
    cnt: Integer;
    str: array[0..MaxInt] of Char;
  end;
  LStrPtr = ^LStr;
  LStrHandle = ^^LStr;
Das wäre eine mögliche Übersetzung, die andere wäre array[0..0] und deaktiviertes Range-Checking.. In beiden Fällen muss beachtet werden, dass die wahre Länge von str niemals über cnt hinausgeht und alle Zugriffe, die jenseits von cnt-1 liegen, nicht gesichert sind.. Eine 100%ige Entsprechung des Codes gibt es, soweit ich weiß, nicht.

OregonGhost 16. Okt 2007 19:13

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Rein interessehalber: Wenn man jetzt eine Variable von diesem Typ anlegt, Dax, werden dann 2 GB reserviert? Oder muss man den Speicher halt von Hand reservieren, damit das sauber läuft?

Dax 16. Okt 2007 19:14

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Zitat:

Zitat von OregonGhost
Rein interessehalber: Wenn man jetzt eine Variable von diesem Typ anlegt, Dax, werden dann 2 GB reserviert? Oder muss man den Speicher halt von Hand reservieren, damit das sauber läuft?

Wenn du eine Variable LStr anlegst, brauchst du 2GB speicher, das ist korrekt. Deswegen sollte man bei solchen Typen, die variable Arrays mit konstanten Grenzen (0..0, 0..N) haben, immer mit Pointern hantieren..

Edit: Delphi macht es in der TList-Implementation auch so: ein Array [0..ziemlichviel] of Pointer (kein dynamisches Array), dass je nach Bedarf per ReallocMem vergrößert und verkleinert wird.

sumara 17. Okt 2007 11:53

So geht's jetzt
 
Mittlerweile hab ich mir aus verschiedenen Antworten (war auch noch in einem anderen Forum) das zusammen gebastelt.
Es klappt, allerdings muss bei der übergabe einer var vom Typ LSTR, wenn cnt auf 0 ist. Ich versteh's ehrlich gesagt nicht so ganz! Hauptsache es geht.

Delphi-Quellcode:
type
  TStr = Array[0..0] of Char;
  LStr = packed record
    cnt: Integer;
    str: ^TStr;
  end;
Das mit den Zeigern hab ich jetzt nicht, weil ich's nicht zum laufen gebracht hab.

Ich übergebe jetzt an die Funktion, die den Parameter: LStrHandle * Parameter erwartet:
Delphi-Quellcode:
Procedure(var param:LStr)
Habt ihr vielleicht noch ein Beispiel, wie's mit den Zeigern aussehen müsste?

Danke.

OregonGhost 17. Okt 2007 12:30

Re: typedef struct aus C++ nach Delphi, LStrHandle LabView
 
Ist der Record nicht falsch? Du hast doch jetzt im Record wieder nur einen Zeiger auf das Array statt des Arrays selbst?


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:33 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