Integer zusammensetzen

OP #6534341
Lesenswert?

Hallo Mikrocontroller-Gemeinde,

wer kann mir mit seinem C#-Wissen weiterhelfen?

Ein PC-Programm empfängt über die serielle Schnittstelle (UART vom µC) 
mehrere Bytes, diese werden im jetzigen Entwurf in ein char Array 
geladen. Die empfangenen Bytes 2-5 sollen nun zu einem 32bit - unsigned 
Integer zusammengesetzt werden.

Beispiel:
Empfangenes Byte 2 = 0x02
Empfangenes Byte 3 = 0xCA
Empfangenes Byte 4 = 0x9A
Empfangenes Byte 5 = 0x38
Die Bytes sollen zu 0x389ACA02 (dezimal 1.000.000.002) zusammengesetzt 
werden und in eine uint32 - Variable gespeichert werden, mit der dann im 
Programm weiter gearbeitet werden kann.

Muss hierfür auch in C# mit Schiebeoperatoren gearbeitet werden?

Danke für Eure Hilfe.
Grüße
Gast #6534396
Lesenswert?

Moritz E. schrieb:
> Bin nicht so Hochsprachen-affin und habe mich gefragt, ob es hier noch
> andere Optionen gibt.

Du könntest mit 256, 65535 und 16777216 multiplizieren. Wenn der 
Compiler schlecht ist, wird das allerdings weniger effizient ausgeführt.

In C gäbe da noch Unions. C# hat das nicht.
Gast #6534460
Lesenswert?

Wenn man es maximal unportabel, aber schnell haben will,
kann man sowas auch als Daten in ein Assemblerfile legen,
statt einer Union in C.
Damit hat man auch die maximale Kontrolle ueber die
Endianness des Resultats.
Das schliesst ein, dass man es auch maximal falsch machen kann.

Schieben und Odern koennen Compiler aber eigentlich auch ganz gut.

Wie gut, dass man in VHDL sowas auch direkt hinschreiben kann.
Gast #6536749
Lesenswert?

Stefan ⛄ F. schrieb:

> In C gäbe da noch Unions. C# hat das nicht.

Aber etwas, womit sich das analog bauen läßt. Die Grundlage ist (wie in 
C) die Struktur, aber die Zugriffssteuerung erfolgt teilweise über 
Attribute. Die dazu nötigen Attribute findet man im Namespace 
System.Runtime.InteropServices.

Allerdings, wie in mehreren Postings bereits angemerkt: man sollte 
solche Sachen aus Gründen der Portabilität besser nicht verwenden, oder 
nur dann, wenn man genau weiss, was man tut. Sonst knallt es z.B. mit 
Mono auf einem ARM gar fürchterlich, obwohl der Code derselbe ist und 
die Quelle nach wie vor dieselben Daten liefert...

Mit dem, was der genannte Namespace liefert, ist es aber durchaus 
möglich, solche Konverterstrukturen auch portabel hinzubekommen. Wenn 
man halt weiss, was man tut...
#6536972
Lesenswert?

c-hater schrieb:
> Sonst knallt es z.B. mit Mono auf einem ARM gar fürchterlich,
> obwohl der Code derselbe ist und die Quelle nach wie vor
> dieselben Daten liefert...

In C mit Unions liegt der Stolperstein in der Endianness des Systems, 
aber meines Wissens laufen Windows, Dotnet, Mono und die dazugehörigen 
Infrastrukturen aber nur auf little-endian-Systemen.

Wo liegt denn das Problem mit "Mono auf ARM" hier?
#6537137
Lesenswert?

Auch in C# gibt es sowas wie Unions:
1
using System;
2
using System.Runtime.InteropServices;
3

4
[StructLayout(LayoutKind.Explicit)]
5
public struct Union
6
{
7
    // Vier Bytes
8
    [FieldOffset(0)] public Byte b1;
9
    [FieldOffset(1)] public Byte b2;
10
    [FieldOffset(2)] public Byte b3;
11
    [FieldOffset(3)] public Byte b4;
12
    // Oder ein Int32
13
    [FieldOffset(0)] public Int32 i;
14
}

Allerdings geht die Diskussion schon völlig über das Problem hinaus. 
Hier reicht als Lösung der Schiebeoperator oder die BitConverter-Klasse 
aus.

Char sollte wie schon erwähnt nicht verwendet werden, weil in C# Zeichen 
UTF-16 kodiert sind (also 16-bit breit). Byte ist die richtige Wahl.

Sofern .NET Core/.NET 5 zum Einsatz kommt, kann man auch über die 
Verwendung von Span<T> nachdenken wenn es um Performance geht.
OP #6542917
Lesenswert?

Hallo nochmal an alle,

ich habe es zwischenzeitlich entsprechend euren Hinweisen umgesetzt, die 
Bytes werden jetzt in ein "echtes" Bytearray gespeichert und durch 
Schieben wieder zu einzelnen Variablen zusammengesetzt.
Zu Beginn war es noch ein Char Array, mit der Umstellung des Encodings 
(vgl. 
https://docs.microsoft.com/en-us/archive/blogs/bclteam/serialport-encoding-ryan-byington) 
lief das auch. Fande die Lösung mit dem Bytearray am Ende aber die 
"sauberere".


An der Stelle somit nochmal danke an Alle für den konstruktiven Input. 
Schön, dass es noch funktionierende Foren ohne Trolls gibt!


Schönes Wochenende

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren