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/)
-   -   Von C++ nach Delphi (Union + Struct) (https://www.delphipraxis.net/160536-von-c-nach-delphi-union-struct.html)

Alter Mann 18. Mai 2011 13:58

Von C++ nach Delphi (Union + Struct)
 
Hallo habe hier eine typedef mit deren Umsetzung ich ein paar Probleme habe:

Code:
typedef union _BM_REQUEST_TYPE {
  struct _BM (
   UCHAR Recpient:2;
   UCHAR Reserved:3;
   UCHAR Type:2;
   UCHAR Dir:1;
  );
  UCHAR B;
} BM_REQUEST_TYPE, *PBM_REQUEST_TYPE;
Ich würde es ja so versuchen:
Delphi-Quellcode:
 BMrec = record
   Recpient: UCHAR;
   Reserved: UCHAR;
   Type   : UCHAR;
   Dir    : UCHAR;
 end;

 _BM_REQUEST_TYPE record
 case Integer of
  0 : (_BM : BMrec);
  1 : (  B : UCHAR);
 end;
Doch was haben die Zahlen im der _BM struct zu bedeuten und ist die union so richtig?
Auch mit Google habe ich noch nichts verwertbares gefunden.

Wie immer: vielen Dank für die Mühe.

implementation 18. Mai 2011 14:03

AW: Von C++ nach Delphi (Union + Struct)
 
Also ich fürchte, die Zahlen stehen für die Bitbelegung, und demnach kannst du das nicht so einfach übersetzen.
2+3+2+1=8, also nimmt das Struct insgesamt 1 Byte ein, während das Record 4 Bytes verbraucht.

Recpient belegt die ersten zwei Bits, kann also Werte von 0 bis 3 enthalten.
Reserved belegt weitere drei Bits und kann Werte von 0 bis 7 enthalten.
Type belegt weitere zwei Bits und kann Werte von 0 bis 3 enthalten.
Dir ist nur ein Bit und kann damit nur 0 oder 1 sein.

Um damit in Delphi umzugehen, musst du wohl oder übel mit And, Shl + Shr arbeiten.

Klaus01 18. Mai 2011 14:09

AW: Von C++ nach Delphi (Union + Struct)
 
.. wäre da BMRec ein Anwendungsfall für Record-Funktionen?

Grüße
Klaus

Alter Mann 18. Mai 2011 14:25

AW: Von C++ nach Delphi (Union + Struct)
 
Okay, ich habe in der Header-Datei etwas weiter gescrollt und dann kamm die
Erklärung für die Zahlen :

Code:
  struct _BM (
   UCHAR Recpient:2;
   UCHAR Reserved:3;
   UCHAR Type:2;
   UCHAR Dir:1;
  );
würde demnach in Delphi so aussehen:
Delphi-Quellcode:
 _BM = record
   Recpient: ARRAY[0..2] of UCHAR;
   Reserved: ARRAY[0..3] of UCHAR;
   Type   : ARRAY[0..2] of UCHAR;
   Dir    : ARRAY[0..1] of UCHAR;
 end;
Aber wie sieht es mit dem union aus?

Danke

implementation 18. Mai 2011 14:41

AW: Von C++ nach Delphi (Union + Struct)
 
Zitat:

Zitat von Alter Mann (Beitrag 1101540)
würde demnach in Delphi so aussehen:
Delphi-Quellcode:
 _BM = record
   Recpient: ARRAY[0..2] of UCHAR;
   Reserved: ARRAY[0..3] of UCHAR;
   Type   : ARRAY[0..2] of UCHAR;
   Dir    : ARRAY[0..1] of UCHAR;
 end;

Falsch. Die Zahlen stehen für Bits, nicht Arrays.

Klaus01 18. Mai 2011 19:31

AW: Von C++ nach Delphi (Union + Struct)
 
Guten Abend,

ich hatte mir das ungefähr so vorgestellt:
Delphi-Quellcode:
interface
type
  BMRec = packed record
    data : Byte;
    function Recipient : Byte;
    function Reserved : Byte;
    function _Type : Byte;
    function Dir : Byte;
  end;

  _BM_REQUEST_TYPE = packed record
    case Integer of
      0 : (_BM : BMRec);
      1 : (B: Byte);
  end;

implementation

 function BMRec.Recipient:Byte;
 begin
   result := (data and $C0) shr 6;
 end;

 function BMRec.Reserved: Byte;
 begin
   result := (data and $37) shr 3;
 end;

 function BMRec._Type: Byte;
 begin
   result := (data and $06) shr 1;
 end;

 function BMRec.Dir : Byte;
 begin
   result := (data and $01);
 end;
Benutzen kann man es so:
Delphi-Quellcode:

procedure TForm1.Button1Click(Sender: TObject);
var
  BM_REQUEST_TYPE : _BM_REQUEST_TYPE;
begin
  edit1.Text := IntToStr(sizeOf(BMRec));
  edit2.Text := intToStr(sizeOf(_BM_REQUEST_TYPE));

  BM_REQUEST_TYPE.B := $80;
  edit3.Text := intToStr(BM_REQUEST_TYPE._BM.Recipient);
end;
Grüße
Klaus

Alter Mann 19. Mai 2011 06:41

AW: Von C++ nach Delphi (Union + Struct)
 
@implementation

Könnte ich das etwas näher erklärt bekommen?

@Klaus01

Schön wäre es gewesen, aber in einem Record bekomme ich keine funktionen unter (D7).

Danke aber trotzdem

OH, ich hätte wohl die vorhergehenden Beiträge mal lesen sollen(peinlich)

Also gut, dann werde ich mich wohl durchquälen müssen.

Danke noch mal.

Robotiker 19. Mai 2011 07:55

AW: Von C++ nach Delphi (Union + Struct)
 
Hallo,

hier ist die Doku zu Bitfeldern beim C++ Builder und Visual C++
http://docwiki.embarcadero.com/RADStudio/en/Bit_Fields
http://msdn.microsoft.com/de-de/library/ewwyfdbe.aspx

Man sollte auch schauen, von welchem C++ Compiler der umzusetzende Code kommt, denn in der C++ Builder Doku steht:

Zitat:

According to the C and C++ language specifications, the alignment and storage of bit fields is implementation defined. Therefore, compilers can align and store bit fields differently. If you want complete control over the layout of bit fields, it is advisable to write your own bit field accessing routines and create your own bit fields.

omata 19. Mai 2011 08:06

AW: Von C++ nach Delphi (Union + Struct)
 
Hier mal mein Vorschlag für D7:

Delphi-Quellcode:
type
  TBMRecContent = (bmRecipient, bmReserved, bmType, bmDir);
  TBMRec = record
    data : Byte;
  end;

  _BM_REQUEST_TYPE = packed record
    case Byte of
      0 : (_BM: TBMRec);
      1 : (B: Byte);
  end;

:

implementation

:

function getBMRecContent(BMRecContent:TBMRecContent; BMRec:TBMRec): Byte;
begin
  case BMRecContent of
    bmRecipient: result := (BMRec.data shr 6) and 3;
    bmReserved: result := (BMRec.data shr 3) and 7;
    bmType:     result := (BMRec.data shr 1) and 3;
    bmDir:      result := (BMRec.data and 1);
  else
    Result:=0;
  end;
end;

procedure TForm.ButtonClick(Sender: TObject);
var BM_REQUEST_TYPE: _BM_REQUEST_TYPE;
begin
  BM_REQUEST_TYPE._BM.data:=3;
  ShowMessage(Format(
    'Recipient = %d, Reserved = %d, Type = %d, Dir = %d',
    [getBMRecContent(bmRecipient, BM_REQUEST_TYPE._BM),
     getBMRecContent(bmReserved, BM_REQUEST_TYPE._BM),
     getBMRecContent(bmType, BM_REQUEST_TYPE._BM),
     getBMRecContent(bmDir, BM_REQUEST_TYPE._BM)]
  ));
end;

Deep-Sea 19. Mai 2011 08:11

AW: Von C++ nach Delphi (Union + Struct)
 
@Klaus01:
Sehr schön. Aber ein Union ist da nicht nötig, da man ja bereits auf BMRec.data zugreifen kann. :wink:

@Alter Mann:
Und warum nutzt du nicht D2009? ^^


PS:
ihmo ist erst schieben und dann Und-Verknüpfen besser zu lesen, da nicht so Werte wie $37 vorkommen.

omata 19. Mai 2011 08:12

AW: Von C++ nach Delphi (Union + Struct)
 
Zweiter Vorschlag:

Delphi-Quellcode:
type
  TBMRecContent = record
    Recipient: Byte;
    Reserved: Byte;
    _Type: Byte;
    Dir: Byte;
  end;

  TBMRec = record
    data : Byte;
  end;

  _BM_REQUEST_TYPE = packed record
    case Byte of
      0 : (_BM: TBMRec);
      1 : (B: Byte);
  end;

:

implementation

:

function getBMRecContent(BM_REQUEST_TYPE:_BM_REQUEST_TYPE): TBMRecContent;
begin
  Result.Recipient:= (BM_REQUEST_TYPE._BM.data shr 6) and 3;
  Result.Reserved:= (BM_REQUEST_TYPE._BM.data shr 3) and 7;
  Result._Type:= (BM_REQUEST_TYPE._BM.data shr 1) and 3;
  Result.Dir:= (BM_REQUEST_TYPE._BM.data and 1);
end;

procedure TForm.ButtonClick(Sender: TObject);
var BM_REQUEST_TYPE: _BM_REQUEST_TYPE;
begin
  BM_REQUEST_TYPE._BM.data:=3;
  ShowMessage(Format(
    'Recipient = %d, Reserved = %d, Type = %d, Dir = %d',
    [getBMRecContent(BM_REQUEST_TYPE).Recipient,
     getBMRecContent(BM_REQUEST_TYPE).Reserved,
     getBMRecContent(BM_REQUEST_TYPE)._Type,
     getBMRecContent(BM_REQUEST_TYPE).Dir]
  ));
end;

Deep-Sea 19. Mai 2011 08:21

AW: Von C++ nach Delphi (Union + Struct)
 
Da fällt mir auf, dass $37 falsch ist, es müsste $38 sein. Ich sag ja: Erst schieben :-D Dann wäre es $07 und der falsche Wert wäre wohl nicht zustande gekommen bzw. schneller aufgefallen.

omata 19. Mai 2011 08:34

AW: Von C++ nach Delphi (Union + Struct)
 
Zitat:

Zitat von Deep-Sea (Beitrag 1101698)
Da fällt mir auf, dass $37 falsch ist, es müsste $38 sein. Ich sag ja: Erst schieben :-D Dann wäre es $07 und der falsche Wert wäre wohl nicht zustande gekommen bzw. schneller aufgefallen.

ups, hab es korrigiert

Deep-Sea 19. Mai 2011 08:41

AW: Von C++ nach Delphi (Union + Struct)
 
Zitat:

Zitat von omata (Beitrag 1101704)
ups, hab es korrigiert

Aber auch net richtig :P
Du musst anstatt mit 2 mit 3 und anstatt mit 3 mit 7 maskieren.
Denn 2 = 0b0010, wir wollen ja aber zwei Bits haben, also 0b0011 = 3 (und für 3 bzw. 7 ebenso) :wink:

omata 19. Mai 2011 08:46

AW: Von C++ nach Delphi (Union + Struct)
 
Hab es wieder korrigiert

Deep-Sea 19. Mai 2011 08:54

AW: Von C++ nach Delphi (Union + Struct)
 
Zitat:

Zitat von omata (Beitrag 1101707)
Hab es wieder korrigiert

Jap, so sollte es stimmen.

Wo ich schon dabei bin, hier mal kurz meine Version:
Delphi-Quellcode:
type
  TRequestType = record
    Recipient: Byte;
    Reserved: Byte;
    Typ: Byte;
    Dir: Boolean;
  end;

implementation

function DecodeRequestType(ARequestType: Byte): TRequestType;
begin
  With Result do
  begin
    Recipient := (ARequestType shr 6) and 3;
    Reserved := (ARequestType shr 3) and 7;
    Typ := (ARequestType shr 1) and 3;
    Dir := (ARequestType and 1) > 0;
  end;
end;

// Ggf. zusätzlich: function EncodeRequestType(ARequestType: TRequestType): Byte;

procedure TForm1.Button1Click(Sender: TObject);
var
  LRequestType: TRequestType;
begin
  LRequestType := DecodeRequestType( { Wert holen } );
  ShowMessageFmt('Recipient = %d, Reserved = %d, Type = %d, Dir = %d',
    [LRequestType.Recipient, LRequestType.Reserved, LRequestType.Typ, Ord(LRequestType .Dir)]);
end;

Alter Mann 19. Mai 2011 10:16

AW: Von C++ nach Delphi (Union + Struct)
 
Danke Leute ihr habt mir sehr geholfen.
Die Doku zu den Bit-Feldern werde ich mir durchlesen (und hoffentlich auch verstehen).

@Deep-Sea: Ich werde deine Version testen. Es dauert nur noch eine Weile denn es sind ein paar
Header-Dateien mehr. Was wäre den in D2009 anders, wenn ich fragen darf?

omata 19. Mai 2011 10:18

AW: Von C++ nach Delphi (Union + Struct)
 
Zitat:

Zitat von Alter Mann (Beitrag 1101730)
Was wäre den in D2009 anders, wenn ich fragen darf?

Funktionen innerhalb eines Records.


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