如果确实使用了 FieldOffset ,是否必须在每个类/结构成员上使用它?



考虑我需要确保类/结构以非常特定的方式映射到内存的情况,可能是由于需要匹配外部协议:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public class SYSTEM_INFO
{
public ulong OemId;
public ulong PageSize;
public ulong ActiveProcessorMask;
public ulong NumberOfProcessors;
public ulong ProcessorType;
}

然后我想做一个"覆盖"(这是一个专有名词吗?(,这样我就可以直接访问内存:

[StructLayout(LayoutKind.Explicit)]
public class SYSTEM_INFO
{
[FieldOffset(0)] public byte[] Buffer = new byte[40]; //overlays all the bytes, like a C union
[FieldOffset(0)] public ulong OemId;
[FieldOffset(8)] public ulong PageSize;
[FieldOffset(16)] public ulong ActiveProcessorMask;
[FieldOffset(24)] public ulong NumberOfProcessors;
[FieldOffset(32)] public ulong ProcessorType;
}

但这变得耗时且容易出错(如果有什么变化,我很容易搞砸更新所有FieldOffset值( - 并且有人指出,由于我不完全理解的原因,实际上无效:

未处理的异常。系统类型加载异常:无法加载类型 程序集"a2bbzf3y.exe的"SYSTEM_INFO2",版本=0.0.0.0, 区域性=中性,公钥令牌=空',因为它包含一个对象 偏移量 0 处的字段未正确对齐或重叠 非对象字段。命令由信号 6 终止

是否可以同时使用这两种方法,其中Buffer覆盖成员,但Buffer之外的所有成员都自动按顺序对齐而不填充?我无法从文档中确定这是否允许,并且我只能在自动决定其他成员的情况下强制某些成员偏移。

struct的情况下,您可以非常轻松地执行此操作 - 坦率地说,如果您正在查看字节,您通常应该使用struct

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
static class P
{
static void Main()
{
var obj = new SystemInfo();
var bytes = AsBytes(ref obj);
Console.WriteLine(bytes.Length); // 40
}
static Span<byte> AsBytes<T>(ref T value)
=> MemoryMarshal.CreateSpan(
ref Unsafe.As<T, byte>(ref value),
Unsafe.SizeOf<T>());
}
public readonly struct SystemInfo
{
public readonly ulong OemId;
public readonly ulong PageSize;
public readonly ulong ActiveProcessorMask;
public readonly ulong NumberOfProcessors;
public readonly ulong ProcessorType;
}

相关内容

  • 没有找到相关文章

最新更新