1

次の状況があります。

struct object1  {

    bool a:1;
    bool b:1;
    uint8_t c:2;
    bool d:1;
    abc  e:3;

    uint16_t header;
    uint8_t footer;
    uint8_t mid[4];
}

私は構文を知らないかもしれませんが、C# でビットを操作するのは C++ ほど簡単ではありません。BitArray クラスと BitConverter クラスを使用してデータを設定するメソッドを作成しましたが、問題が発生しました。

object1 * rqr = (object1  *) &Msg.Data[2];

基本的に、オブジェクトをバイト配列にキャストしています。私が行ったすべての検索はシリアライゼーションを叫びますが、上記の行を真に変換するために、追加のメタデータなどを持つことはできません。

私は本当にメモリの場所へのポインタを作成し、その場所をそのオブジェクトに「キャスト」したいと思っています。これは可能ですか?そうでない場合、この問題の解決策はありますか? このレベルのビット操作が完全に取り除かれているとは思えません。私はそれを仮定する前に知らないだけでデフォルトします。

編集:: C# では管理型へのポインターが許可されていないことを理解しています。私が求めているのは、次のように言う方法があったかどうかです。

Byte[] ayData = new Byte[8];
ObjectOfSize8 nObject =  (ObjectOfSize8)ayData;

上記が機能しないことは理解していますが、オブジェクトのメモリサイズを理解できるほど頭が良ければ、言語にデータキャストを許可するものはありますか?

4

2 に答える 2

2

ビットシフトとマスキングを処理する構造体を使用して、ビットフィールドの問題を解決できます。

[StructLayout(LayoutKind.Sequential, Size=1)]
public struct BitField8
{
    private byte _bits;

    private static readonly byte[] Masks = new byte[] { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    public BitField8(int val)
    {
        _bits = (byte) val;
    }

    public byte Get(int bit, int length = 1)
    {
        int shift = bit + length - 1;
        return (byte) ((_bits >> shift) & Masks[length-1]);
    }

    public void Set(int bit, int length, int val)
    {
        int mask = Masks[length-1];
        int shift = bit + length - 1;
        val = (val & mask) << shift;
        mask = ~(mask << shift);
        _bits = (byte)((_bits & mask) | val);
    }
}

あなたの例では:

bool a:1;
bool b:1;
uint8_t c:2;
bool d:1;
abc  e:3;

a呼び出して設定しますSet(0, 1, 1)(a を 1 に設定)。

3 の値を指定するにcは、 を呼び出しますSet(3, 2, 3)。(cビット 2 と 3 を占有します)。

これは基本的に C++ ビットフィールドの機能を複製しますが、ビットの順序が間違っている可能性があることは認めます。aC++ コンパイラがビット 0 またはビット 7 に配置したかどうかはよくわかりません。

16 ビット、32 ビット、および 64 ビットのビットフィールドでも同様のことができます。

したがって、構造体には次が含まれます。

BitField8 myBitfield;
于 2013-08-05T22:27:58.643 に答える
1

C# の型キャストでは、要求したことを行うことはできません。必要なことを行う最もクリーンな方法は、C# 構造体を固定することだと思います。次に、Marshal.Copy で使用してバイト配列との間でコピーできる IntPtr を取得します。

ビットフィールドに関しては、ビットごとのシフト、ビットごとの OR、およびビットごとの AND 操作を使用して管理する必要があります。

于 2013-08-05T22:23:02.883 に答える