托管结构的大小

dtb*_*dtb 12 c# .net-4.0

.NET 4.0 Framework引入了用于读取和写入内存映射文件的类.这些类以读取写入结构的方法为中心.这些不是编组的,而是以它们在托管内存中布局的形式从文件复制到文件.

假设我想使用以下方法将两个结构顺序写入内存映射文件:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Foo
{
    public char C;
    public bool B;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Bar
{
}

static void Write<T1, T2>(T1 item1, T2 item2)
    where T1 : struct
    where T2 : struct
{
    using (MemoryMappedFile file = MemoryMappedFile.CreateNew(null, 32))
    using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor())
    {
        accessor.Write<T1>(0L, ref item1);  //  <-- (1)
        accessor.Write<T2>(??, ref item2);  //  <-- (2)
    }
}

static void Main()
{
    Foo foo = new Foo { C = '?', B = true };
    Bar bar = new Bar { };
    Write(foo, bar);
}
Run Code Online (Sandbox Code Playgroud)

如何获得(1)中写入的字节数,以便在(2)中相邻写入下一个值?

注意:示例中的字节数为3(= 2 + 1),而不是Marshal.SizeOf返回的5(= 1 + 4).

注2:sizeof无法确定泛型类型参数的大小.

Pen*_*puu 4

似乎没有记录/公共的方法来访问SizeOfType类使用的内部函数MemoryMappedViewAccessor,因此获取这些结构的大小的最实用的方法是使用像这样的反射:

static readonly Func<Type, uint> SizeOfType = (Func<Type, uint>)Delegate.CreateDelegate(typeof(Func<Type, uint>), typeof(Marshal).GetMethod("SizeOfType", BindingFlags.NonPublic | BindingFlags.Static));

static void Write<T1, T2>(T1 item1, T2 item2)
    where T1 : struct
    where T2 : struct
{
    using (MemoryMappedFile file = MemoryMappedFile.CreateNew(null, 32))
    using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor())
    {
        accessor.Write(0, ref item1);
        accessor.Write(SizeOfType(typeof(T1)), ref item2);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是我现在正在做的事情。我希望有一个更清洁的解决方案。在我看来,依赖内部的、未记录的方法并不是一个好主意。 (2认同)