![]() |
32 Bit Wert verschieden interpretieren
Hallo,
ich bekomme über eine Schnittstelle 32 Bit Werte. Diese sind aber manchmal Single Zahlen, Longword und manchmal LongInt. Wenn ich diese falsch "anfasse", kommt immer wieder Fehler bei Bereichsüberschreitung. Wie macht ihr das? Nehmt ihr mehrere verschiedene Variablen und deklariert sie dann über absolute auf die selbe Adresse oder wie macht ihr das? |
AW: 32 Bit Wert verschieden interpretieren
Inwiefern werden die "falsch angefaßt"? Beispielcode?
|
AW: 32 Bit Wert verschieden interpretieren
Ist ein wenig schwer zu erklären.
Wie gesagt, ich bekomme 4 Bytes und muss diese unterschiedlich interpretieren (single, longword, longint). Dann muss dieser Wert aber wieder an eine Funktion weitergereicht werden. Da ich aber nur diese 4 Bytes habe, weiß ich nicht, wie ich diese dann weiterreichen kann. WriteToSvr(Adr, v) wobei hier v ein single wäre WriteToSvr(Adr, v) wobei hier v ein longword wäre WriteToSvr(Adr, v) wobei hier v ein longint wäre Vielleicht irgendein Pointer, der alles beinhalten kann? |
AW: 32 Bit Wert verschieden interpretieren
Zum Prüfen
Delphi-Quellcode:
Ok, ich sehe du brauchst, LongInt, LingWord und Double. LongInt kannst du mit der oberen Funktion testen, für Single kannst du dir mit TryStrToFloat eine Funktion erstellen.
{ Prüft ob String ein Integerwert ist }
function IsValidInteger(S: String): Boolean; var I, Code: Integer; begin Val(S, I, Code); Result := Code = 0; end; { Prüft ob String ein Currencywert ist } function IsValidCurrency(S: String): Boolean; var C: Currency; begin Result := TextToFloat(PChar(S), C, fvCurrency); end; { Prüft ob String ein Extendedwert ist } function IsValidExtended(S: String): Boolean; var E: Extended; begin Result := TextToFloat(PChar(S), E, fvExtended); end;
Delphi-Quellcode:
function TryStrToFloat(const S: string; out Value: Double): Boolean; overload;
//Ungeprüft { Prüft ob String ein Double ist } function IsValidDouble(S: String): Boolean; var Value: Double ; begin Result := TryStrToFloat(S, Value); end; |
AW: 32 Bit Wert verschieden interpretieren
Ich kann das vielleicht nicht so richtig rumbringen.
Als Quelle kommen 4 Bytes an. Durch Festlegung weiß ich, dass es Single, Longword oder LongInt ist. Diese können dann mittels verschiedener Spinedits verändert werden. Dazu habe ich dann an Hand der Kennung den Wert jeweils in ein Single, Longword oder LongInt gespeichert. Nun muss ich aber die verschiedenen Werte wieder über eine Funktion wieder in die 4 Bytes zurückbekommen. Vielleicht muss ich irgendwie mit overload arbeiten? |
AW: 32 Bit Wert verschieden interpretieren
Also nochmal, du muß es nicht prüfen, du weißt ob es Single, LongInt, LongWord ist, du willst nur wissen wie du es weiter leiten kannst?
|
AW: 32 Bit Wert verschieden interpretieren
Zitat:
|
AW: 32 Bit Wert verschieden interpretieren
Zitat:
Zitat:
|
AW: 32 Bit Wert verschieden interpretieren
Hilft dir das weiter?
Delphi-Quellcode:
Und wie gesagt, ob du d oder i oder w als Variable nimmst, mußt du selbst vorher prüfen.
procedure MyTest(Value: Double); overload;
begin ShowMessage(FloatToStr(Value)); end; procedure MyTest(Value: LongInt); overload; begin ShowMessage(IntToStr(Value)); end; procedure MyTest(Value: LongWord); overload; begin ShowMessage(IntToStr(Value)); end; procedure TForm1.Button1Click(Sender: TObject); var d: Double; i: LongInt; w: LongWord; begin d := 1.7e308; i := -2147483647; w := 4294967295; MyTest(d); MyTest(i); MyTest(w); end; |
AW: 32 Bit Wert verschieden interpretieren
Zitat:
Vielen Dank. |
AW: 32 Bit Wert verschieden interpretieren
Ich habs nun mal so gemacht. Muss nur noch testen. Das Array ar4 enthält dann die 4 Bytes, unabhängig, ob es Single, LongWord oder LongInt ist.
Delphi-Quellcode:
Function WriteToSvr(Address: Longword; dValue: Longword): Boolean; overload;
var Adr1 : Longword; Wert : Longword; ar: ar4 absolute Wert; begin Result := False; Adr1 := Address; Wert := dValue; If WriteToSvr3(Adr1, ar) then begin Result := True; end; end; Function WriteToSvr(Address: Longword; dValue: LongInt): Boolean; overload; var Adr1 : Longword; Wert : LongInt; ar: ar4 absolute Wert; begin Result := False; Adr1 := Address; Wert := dValue; If WriteToSvr3(Adr1, ar) then begin Result := True; end; end; Function WriteToSvr(Address: Longword; dValue: Single): Boolean; overload; var Adr1 : Longword; Wert : Single; ar: ar4 absolute Wert; begin Result := False; Adr1 := Address; Wert := dValue; If WriteToSvr3(Adr1, ar) then begin Result := True; end; end; |
AW: 32 Bit Wert verschieden interpretieren
Mit einem varianten Record sollte das aber auch funktionieren, und zwar kürzer.
Delphi-Quellcode:
type
TConvRec = record case integer of 0: (d: double); 1: (i: LongInt); 2: (w: LongWord); 3: (LoLo, HiLo, LoHi, HiHi: Byte); end; procedure TForm1.Button1Click(Sender: TObject); var Rec: TConvRec; begin Rec.i := -2147483647; ShowMessage(Format('%d, %d, %d, %d', [Rec.HiHi, Rec.LoHi, Rec.HiLo, Rec.LoLo])); Rec.w := 4294967295; ShowMessage(Format('%d, %d, %d, %d', [Rec.HiHi, Rec.LoHi, Rec.HiLo, Rec.LoLo])); Rec.d := 1.7e308; ShowMessage(Format('%d, %d, %d, %d', [Rec.HiHi, Rec.LoHi, Rec.HiLo, Rec.LoLo])); end; |
AW: 32 Bit Wert verschieden interpretieren
Für mich hört sich das sehr danach an als ob du z.B. einen varianten Record suchst... ungetestetes Beispiel, das sollte mit Delphi 2009 schon gehen:
Delphi-Quellcode:
Ich sehe schon die rote Box, aber ich poste wegen dem Operator mal trotzdem...
type
TMy4ByteData = packed record type TDataType = (dtSingle, dtInteger, dtLongWord); class operator implicit(const Value: TMy4ByteData): TArray<Byte>; case DataType: TDataType of dtSingle: (ValueAsSingle: Single); dtInteger: (ValueAsInteger: Integer); dtLongWord: (ValueAsLongWord: LongWord); end; // ... class operator TMy4ByteData.implicit(const Value: TMy4ByteData): TArray<Byte>; begin SetLength(Result, 4); CopyMemory(Pointer(Result), @Value.ValueAsInteger, 4); end; procedure Example(const AValue: TMy4ByteData); begin case AValue.DataType of dtSingle: ShowMessage('Single: ' + FloatToStr(AValue.ValueAsSingle)); dtInteger: ShowMessage('Integer: ' + IntToStr(AValue.ValueAsInteger)); dtLongWord: ShowMessage('LongWord: ' + IntToStr(AValue.ValueAsLongWord)); end; end; var Value: TMy4ByteData; ValueData: TArray<Byte>; CurrentByte: Byte; begin Value.DataType := dtSingle; Value.ValueAsSingle := 4.5; Example(Value); ValueData := Value; for CurrentByte in ValueData do ShowMessage(IntToStr(CurrentByte)); end; |
AW: 32 Bit Wert verschieden interpretieren
Wieso das
Delphi-Quellcode:
nicht so?
If WriteToSvr3(Adr1, ar) then begin
Result := True; end;
Delphi-Quellcode:
Result := WriteToSvr3(Adr1, ar);
|
AW: 32 Bit Wert verschieden interpretieren
Zitat:
Ich hatte in dem Zweig ursprünglich noch etwas anderes drin. Aber jetzt nicht mehr. So könnte ich den Code noch ein wenig schlanker machen. |
AW: 32 Bit Wert verschieden interpretieren
Dann kannst du auch
Delphi-Quellcode:
entfernen.
Result := False;
|
AW: 32 Bit Wert verschieden interpretieren
Zitat:
Das mit den varianten Records muss ich mir mal später genauer anschauen. Vielleicht kann das später in mein Projekt mit reinwachsen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:50 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