Autor |
Beitrag |
Sumara
Hält's aus hier
Beiträge: 8
|
Verfasst: Di 16.10.07 16:59
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:
Quelltext 1: 2: 3: 4:
| 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!
Bisher hab ichs mit folgenden typen versucht:
Delphi-Quelltext 1:
| 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.
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Di 16.10.07 19:08
Hi,
auch wenn ich nicht wirklich ein C++ genie bin und da auch immer mal wieder gerne in fallen tappe, aber ich würde es so interpretieren:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| type LStr = packed record cnt: Integer; str: Char; end; LStrPtr: ^LStr; LStrHandle: ^LStrPtr; |
wobei ich nicht verstehe warum das "str" ein Array ist... ausser es wird dann einfach ein Array an der stelle zurückgegeben und nur der Pointer gesetzt, dann müßte es denke ich so aussehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| type TStr = Array[0..0] of Char; LStr = packed record cnt: Integer; str: ^TStr; end; LStrPtr: ^LStr; LStrHandle: ^LStrPtr; |
Drauf zugreifen kannst du dann einfach wie bei einem normalen Array, also z.B.:
Delphi-Quelltext 1: 2:
| for i:=0 to myLStr.cnt - 1 do DoSomethingWith(myLStr.str[i]); |
Aya~
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 17.10.07 11:01
UChar in C\C++ ist Byte in Delphi., ansonsten sollte das soweit stimmen ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sinspin
      
Beiträge: 1335
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mi 17.10.07 11:42
Ganz große Vorsicht mit solchen C/C++ Typdeklarationen!
Das was bei einem solchen Typ zurück geliefert werden kann, kann 5 Byte aber auch 5000 Byte, oder viel mehr sein.
Relevant ist, das als erstes bei einem solchen Typ immer die Größe des Datensatzes geliefert wird und im Anschluss eine variable Menge an Daten, mindestens aber ein Byte.
Quelltext 1: 2: 3: 4:
| typedef struct { int32 cnt; /* number of bytes that follow */ uChar str[1]; /* cnt bytes */ } LStr, *LStrPtr, **LStrHandle; |
Zusammen kommt man so : int32 = 4 byte + uChar = 1 Byte -> 5 Byte.
in delphi würde sowas so aussehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| type LStr = packed record cnt: Integer; str: Array[0..0] of Char; end; LStrPtr: ^LStr; LStrHandle: ^LStrPtr; |
Ob "packed" oder nicht ist wieder so eine Frage. Das hängt von der Datenausrichtung in der DLL ab. Geh einfach mal davon aus das es so passt.
Die Deklaration
Delphi-Quelltext 1:
| str: Array[0..0] of Char; |
sieht zwar komisch aus, ermöglicht es aber einfach auf die Daten in str zu zugreifen.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
Sumara 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 17.10.07 12:56
Titel: Problem gelöst
Mittlerweile hab ich mir aus verschiedenen Antworten (war auch noch in einem anderen Forum) das zusammen gebastelt.
Das passt ja auch zu dem was SinSpin sagt.
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-Quelltext 1: 2: 3: 4: 5: 6:
| 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-Quelltext 1:
| Procedure(var param:LStr) |
Habt ihr vielleicht noch ein Beispiel, wie's mit den Zeigern aussehen müsste?
Danke.
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mi 17.10.07 13:21
Das mit dem Zeiger ist Falsch. Denn ein Zeiger würde einen dynamischem Array gleich kommen. Was in diesem Falle aber ja nicht der Fall ist, da die Daten nun mal direkt mit in dem Record stecken. Solche Records kannst du aber auch nicht normal benutzen die müssen grundsätzlich immer über GetMem erstellt werden. In C/C++ auch, wenn ich mich nicht vertue. Wenn man sie selbst Erstellen muss.
Im Übrigen solltest du die Bereichprüfung dann bei der Benutzung aussstellen. Aber das mit dem Array[1..1] ist mehr oder weniger der einzig funktionierende Weg.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Sinspin
      
Beiträge: 1335
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mi 17.10.07 14:12
Lossy eX hat folgendes geschrieben: | Das mit dem Zeiger ist Falsch. Denn ein Zeiger würde einen dynamischem Array gleich kommen. Was in diesem Falle aber ja nicht der Fall ist, da die Daten nun mal direkt mit in dem Record stecken. Solche Records kannst du aber auch nicht normal benutzen die müssen grundsätzlich immer über GetMem erstellt werden. In C/C++ auch, wenn ich mich nicht vertue. Wenn man sie selbst Erstellen muss.
Im Übrigen solltest du die Bereichprüfung dann bei der Benutzung aussstellen. Aber das mit dem Array[1..1] ist mehr oder weniger der einzig funktionierende Weg. |
Ich schließe mich deiner Meinung an. So wie ich den Record deklariert habe müsste es gehen, wenn man nicht eine Variable sondern einen Zeiger auf ein Stück Speicher des Types übergeben wird.
Nur ist ja in diesem Fall das Interessante das man nichts übergibt, sondern was bekommt. Das heißt der Speicher wird in der Procedure angelegt und die Adresse an den Zeiger übergeben.
Was ja eigentlich bedeutet das man einfach nur einen Zeiger auf diesen Typ übergeben bräuchte.
-- habe ich schonmal erwähnt das ich C/C++ nicht für den ganz großen Wurf halte? --
Delphi-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:
| type LStr = packed record cnt: Integer; str: Array[0..0] of Char; end; LStrPtr: ^LStr; LStrHandle: ^LStrPtr;
procedure DoIt; var myPtrStr: LStrPtr; l: integer;
begin GetMem(myPtrStr, SizeOf(LStrPtr)); Initialize(myPtrStr, SizeOf(LStrPtr)); DeineProc(myPtrStr^); {$R-} for l := 0 to myPtrStr^.cnt-1 do {$R+} FreeMem(myPtrStr); end; |
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 18.10.07 12:59
Alternativ sollte das auch so gehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| type LStr = packed record cnt: Integer; str: record end; end; LStrPtr: ^LStr; LStrHandle: ^LStrPtr; |
Wichtig bei dieser Definition ist, dass die C-Semantik übernommen wird, Delphi aber als größe nur die ersten 4 Byte liefert. Von daher vorsicht in DElohi mit dieser Variante.
Der Zugriff auf die Daten erfolgt mit Move.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|