我有以下情况:
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;
我知道上面的方法行不通,但是,如果您足够聪明,可以理解对象的内存大小,那么语言中是否有某些东西可以允许数据转换?
最佳答案
您可以使用为您处理位移位和屏蔽的结构来解决您的位域问题:
[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;
您可以通过调用 Set(0, 1, 1)
来设置 a
(将 a 设置为 1)。
要将 c
的值设为 3,您可以调用 Set(3, 2, 3)
。 (c
占用位 2 和 3)。
这基本上复制了 C++ 位域的功能,尽管我承认我的位顺序可能有误。我真的不知道 C++ 编译器是将 a
放在第 0 位还是第 7 位。
您可以对 16 位、32 位和 64 位位域执行类似的操作。
所以你的结构将包含:
BitField8 myBitfield;
关于c# - C++ 转换为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18068146/