You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何高效将字节数组复制到结构体数组?

快速将字节数组复制到结构体数组的实现方案

针对你的需求,这里提供两种高效的实现方式,优先推荐内存指针直接复制的unsafe方案(速度最快);如果无法启用unsafe代码,可使用Marshal类的替代方案。

方案一:Unsafe内存指针复制(性能最优)

这种方式直接操作内存块,完全避免额外的类型转换开销,是性能最优的选择。需要先在项目属性中勾选「允许不安全代码」。

asVarGroups = new TsVarGroup[sVarTable.Count];
// 自动获取结构体大小,避免硬编码错误
int structSize = Marshal.SizeOf<TsVarGroup>();
byte[] dataVarGroups = Connection.GETMEM("R", (sVarTable.Addr - ADDRESS_OFFSET), asVarGroups.Length * structSize);

unsafe
{
    fixed (byte* srcPtr = dataVarGroups)
    fixed (TsVarGroup* destPtr = asVarGroups)
    {
        // 直接复制整个内存块
        Buffer.MemoryCopy(srcPtr, destPtr, asVarGroups.Length * structSize, dataVarGroups.Length);
    }
}

原理:你的结构体已标记LayoutKind.Sequential和Pack=1,内存布局与字节数组完全对齐,通过指针直接复制内存即可完成批量转换,fixed数组NamePrefix的内容会被完整复制,后续调用GetNamePrefix()可正常获取字符串。

方案二:Marshal类转换(无需unsafe)

如果项目无法启用unsafe代码,可使用Marshal类完成内存块到结构体的转换,性能略低于unsafe方案,但实现简单。

asVarGroups = new TsVarGroup[sVarTable.Count];
int structSize = Marshal.SizeOf<TsVarGroup>();
byte[] dataVarGroups = Connection.GETMEM("R", (sVarTable.Addr - ADDRESS_OFFSET), asVarGroups.Length * structSize);

// 固定字节数组,避免GC移动内存
GCHandle dataHandle = GCHandle.Alloc(dataVarGroups, GCHandleType.Pinned);
try
{
    IntPtr srcBasePtr = dataHandle.AddrOfPinnedObject();
    for (int i = 0; i < asVarGroups.Length; i++)
    {
        // 逐个将内存块转换为结构体
        asVarGroups[i] = Marshal.PtrToStructure<TsVarGroup>(srcBasePtr + i * structSize);
    }
}
finally
{
    // 释放固定句柄
    dataHandle.Free();
}

关键注意事项

  • 务必使用Marshal.SizeOf<TsVarGroup>()获取结构体大小,不要硬编码TS_VARGROUP_SIZE,避免结构体修改后出现大小不匹配的问题。
  • 保持结构体的StructLayout设置不变(Sequential+Pack=1),确保内存布局与字节流完全一致,无额外对齐填充。

内容的提问来源于stack exchange,提问作者jirikk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:35