我的目标是将字节数组转换为C# struct ,然后再转换回来.假设我从外部来源收到以下数据:

byte[] bytes = {
    0x10, 0x00,
    0x01, 0x00, 0x01, 0x00
};

我知道前两个字节表示"ushort"值,接下来4个字节表示"uint".字节按"高端"顺序排列.为了保存解码结果,我声明以下 struct :

struct Envelop
{
    public ushort Value1;
    public uint Value2;
}

现在我想创建一个"Envelop"的实例,并根据数据填充它.有没有标准的功能呢?

Envelop data = SomeStandardFunctionality<Envelop>(bytes);

Console.WriteLine(data.Value1); // 16
Console.WriteLine(data.Value2); // 257

我还需要将此 struct 转换回数组的可能性,该数组应该与初始 struct 完全相同.我相信这两个任务都是C#中相同功能的一部分.

推荐答案

最接近的,你可以得到不进入非常不安全的领域是,分别读取值使用BinaryPrimitives.

var data = new Envelop
{
    Value1 = BinaryPrimitives.ReadUInt16LittleEndian(bytes),
    Value2 = BinaryPrimitives.ReadUInt32LittleEndian(bytes[2..])
};

Console.WriteLine(data.Value1); // LittleEndian: 16, BigEndian: 4096
Console.WriteLine(data.Value2); // LittleEndian: 65537, BigEndian 16777472

如果你想直接复制内存,你可以这样做,但这是相当不安全的,因为你的结果将取决于系统的endianess.

var data = new Envelop();
var ptr = new IntPtr(&data);
Marshal.Copy(bytes, 0, ptr, bytes.Length);

Console.WriteLine(data.Value1); // 16
Console.WriteLine(data.Value2); // 65537

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Envelop
{
    public ushort Value1;
    public uint Value2;
}

Csharp相关问答推荐

Regex在c#中完全匹配

EF Core 8—应用客户端投影后无法转换集操作

有没有一种方法可以在包含混合文本的标签中嵌入超链接?

如何从HttpContext获取请求正文

如何注销Microsoft帐户?

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

默认情况下,.NET通用主机(Host.CreateDefaultBuilder)中是否包含UseConsoleLifetime?

在实体框架中处理通用实体&S变更跟踪器

在ASP.NET Core Web API项目中通过中间件修改`Request.Path`不会更改使用的控制器/操作

如何使用EF Core和.NET 8来upsert到具有多对多关系的表?

System.Text.Json .NET 8多形态语法化

什么类型的对象存储在大对象堆(LOH)中

如何防止Visual Studio断点以红色突出显示到整行?

实体框架-IsRequired()与OnDelete()

解决方案:延长ABP框架和ANGING OpenIddict中的令牌生命周期

Linq SELECT的多条指令

Xamarin.Forms项目中缺少MainPage.xaml

最小API定义的Swagger标头参数

无法创建工具窗口(用于VBIDE、VBA的COM加载项扩展)

无法通过服务控制台启动.NET Core 6.0服务(错误1053)