fieldoffset,union

03/09/2008 - 11:00 von Michael Meier | Report spam
ich habe folgendes struct:

[StructLayout(LayoutKind.Explicit)]
public struct Readingstates
{
[FieldOffset(0)]
public ulong allstates;

[FieldOffset(0)]
public bool connection; // connection lost

[FieldOffset(1)]
public bool initialization; // missing incoming initialization

[FieldOffset(2)]
public bool syncronisation; // counter error

[FieldOffset(3)]
public bool reference; // has seen reference
};

damit will ich eigentlich ein bitfeld darstellen, bei dem allstates immer
alle bits zusammenfasst.
hintergrund: in c++ gab es dazu unions:
union ReadingStates
{
USHORT allstates;
struct state_t
{
USHORT connection : 1; // connection lost
USHORT initialization : 1; // missing initialization
USHORT syncronisation : 1; // counter error
USHORT reference : 1; // has seen reference
}state;
};

was passieren soll:
Readingstates statesManaged = new Readingstates();
statesManaged.allstates = 0; // => alles 0
statesManaged.state.connection = 1; // => connection=1, allstates=1
statesManaged.state.initialization = 1; // => initialization=1,
allstates=3
statesManaged.state.connection = 0; // => connection=0, allstates=2
statesManaged.allstates = 0; // => alles 0
statesManaged.allstates = 3; // => connection=1,
initialization=1, allstates=3

und was passiert:
Readingstates statesManaged = new Readingstates();
statesManaged.connection = true; // => connection=true, allstates=1
(OK)
statesManaged.initialization = true; // => initialization=true,
allstates%7
statesManaged.connection = false; // => connection=false, allstates%6
(
statesManaged.allstates = 0; // => alles 0/false
statesManaged.allstates = 3; // => connection=true,
initialization=false, allstates=3

es funktioniert also nicht so, wie es soll und mit dem union auf
funktioniert.
es sieht wohl so aus, daß ":1" in c++ dem feld tatsàchlich ein bit platz
eingeràumt hat, in c# rechnet aber fieldoffset stets mit bytes statt mit
bits? (statesManaged.initialization = true setzt ja das erste bit im 2.
byte, es soll aber eigentlich das 2. bit im ersten byte setzen).
das attribut zu àndern in [StructLayout(LayoutKind.Explicit, Pack=1)] hat
auch nichts gebracht.

weiß jemand abhilfe bzw. ob und wie die gewünschte funktionalitàt
überhaupt in c# passt?

klar, als alternative geht immer, die felder per setter/getter zu
setzen/schreiben, was jedoch schnell mühselig sein kann, wegen:
- es gibt einige unions die nachgebildet werden müssen
- setzen der einzelnen felder wenn allstates gesetzt wird
- das schlimmste: die umsetzung eines unions in eine solche klasse muß
dann jedesmal "manuell" passieren, also durch einen eigene methode,
einfach per Marshal.PtrToStructure wird da nichts laufen.

weiß jemand rat?


micha
 

Lesen sie die antworten

#1 Frank Dzaebel
03/09/2008 - 11:48 | Warnen spam
Hallo Michael,

ich habe folgendes struct: [...]



Du hast alles richtig gemacht, nur hast Du
das als falsch interpretiert, da Du vermutlich
angenommen hast, die würden als Bits
nebeneinanderstehen. Ein FieldOffset ist aber
der Offset in Bytes! Siehe analog auch:

[Unions in C#]
http://www.aspheute.com/artikel/20020207.htm

Deine Bits sehen doch dann in der Reihenfolge
so aus, denn es sind doch jeweils nur hintereinander
gestellte *bytes* !

allstates=000001 ->1 (state.connection = 1;)
allstates=00000100000001 -> 257 (state.initialization = 1;)


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen