我正在开发一种工具,该工具必须符合规范,该规范将大量数据打包成跨字节边界的位。示例:2 字节编码 2 个字段,10 位值,6 位容差。其他字段可能跨越 2-4 个字节并分成更多字段。
与其与 C# 斗争并尝试使用位域(如在 C++ 中)获得结构,我想另一种选择是在发送/接收数据之前创建通用位打包/解包函数,并使用标准类型在 C# 中处理所有数据:字节,短,整数,长等。
我是 C# 新手,所以我不确定解决这个问题的最佳方法。从我读过的内容来看,unsafe
不鼓励与指针一起使用,但我尝试使用泛型类型的尝试失败了:
private static bool GetBitsFromByte<T,U>(T input, byte count, out U output, byte start = 0) where T:struct where U:struct
{
if (input == default(T))
return false;
if( (start + count) > Marshal.SizeOf(input))
return false;
if(count > Marshal.SizeOf(output))
return false;
// I'd like to setup the correct output container based on the
// number of bits that are needed
if(count <= 8)
output = new byte();
else if (count <= 16)
output = new UInt16();
else if (count <= 32)
output = new UInt32();
else if (count <= 64)
output = new UInt64();
else
return false;
output = 0; // Init output
// Copy bits out in order
for (int i = start; i < count; i++)
{
output |= (input & (1 << i)); // This is not possible with generic types from my understanding
}
return true;
}
我会用类似这样的方法调用该方法,将 10 位(来自 LSB)从data_in
into中拉出data_out
,接下来的 6 位从data_in
into中拉出next_data_out
。
Uint32 data_in = 0xdeadbeef;
Uint16 data_out;
byte next_data_out;
if(GetBitsFromByte<Uint32,Uint16>(data_in, 10, out data_out, 0))
{
// data_out should now = 0x2EF
if(GetBitsFromByte<Uint32,byte>(data_in, 6, out next_data_out, data_out.Length))
{
// next_data_out should now = 0x2F
}
}
我宁愿不必为byte
, ushort
, uint
,的所有可能组合编写函数ulong
,尽管我想这是另一种选择。
我已经看过BitConverter
类,但那是针对不操作位的字节数组。我也明白我不能做类似的事情:where T : INumeric
or where T : System.ValueType
,所以我愿意接受建议。
谢谢!