标签: layoutkind.explicit

当子结构具有LayoutKind.Explicit时,不遵循LayoutKind.Sequential

运行此代码时:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace StructLayoutTest
{
    class Program
    {
        unsafe static void Main()
        {
            Console.WriteLine(IntPtr.Size);
            Console.WriteLine();


            Sequential s = new Sequential();
            s.A = 2;
            s.B = 3;
            s.Bool = true;
            s.Long = 6;
            s.C.Int32a = 4;
            s.C.Int32b = 5;

            int* ptr = (int*)&s;
            Console.WriteLine(ptr[0]);
            Console.WriteLine(ptr[1]);
            Console.WriteLine(ptr[2]);
            Console.WriteLine(ptr[3]);
            Console.WriteLine(ptr[4]);
            Console.WriteLine(ptr[5]);
            Console.WriteLine(ptr[6]);
            Console.WriteLine(ptr[7]);  //NB!


            Console.WriteLine("Press any key");
            Console.ReadKey();
        }

        [StructLayout(LayoutKind.Explicit)]
        struct Explicit
        {
            [FieldOffset(0)]
            public int Int32a;
            [FieldOffset(4)]
            public int Int32b;
        }

        [StructLayout(LayoutKind.Sequential, Pack …
Run Code Online (Sandbox Code Playgroud)

.net c# unsafe structlayout layoutkind.explicit

13
推荐指数
1
解决办法
1655
查看次数

使用LayoutKind.Explicit的布尔编组,这是否已按设计破坏或失败?

首先,布尔类型被称为具有四字节值的默认编组类型.以下代码有效:

    struct A 
    { 
        public bool bValue1; 
        public int iValue2; 
    }
    struct B 
    { 
        public int iValue1;
        public bool bValue2; 
    }
    public static void Main()
    {
        int[] rawvalues = new int[] { 2, 4 };

        A a = (A)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(A));
        Assert.IsTrue(a.bValue1 == true);
        Assert.IsTrue(a.iValue2 == 4);
        B b = (B)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(B));
        Assert.IsTrue(b.iValue1 == 2);
        Assert.IsTrue(b.bValue2 == true);
    }
Run Code Online (Sandbox Code Playgroud)

显然,这些结构独立编组就好了.值按预期转换.但是,当我们将这些结构组合成一个"联合"时,通过声明LayoutKind.Explicit,如下所示:

    [StructLayout(LayoutKind.Explicit)]
    struct Broken
    {
        [FieldOffset(0)]
        public A a;
        [FieldOffset(0)]
        public B b;
    }
Run Code Online (Sandbox Code Playgroud)

我们突然发现自己无法正确编组这些类型.以下是上述结构的测试代码及其失败方式:

        int[] rawvalues = new int[] …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke boolean marshalling layoutkind.explicit

5
推荐指数
1
解决办法
1233
查看次数

在发布版本中,使用重叠编组LayoutKind.Explicit结构失败

我有一个结构,其中一个非重叠字段报告为重叠.

[FieldOffset(8)]
Int32 X;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
[FieldOffset(12)]
string Y;

[FieldOffset(28)]
int Z;
Run Code Online (Sandbox Code Playgroud)

报告的错误是:

无法加载类型'XXX'...它包含偏移12处的对象字段,该字段未正确对齐或由非对象字段重叠.

它仅在Release配置中发生(TRACE,DEBUG标志和不安全代码被启用,优化被关闭),猜测 - 它会发生什么?

UPD:感谢@svick.确认x64构建不是人们想要的编组.

c# marshalling layoutkind.explicit

3
推荐指数
2
解决办法
1208
查看次数

LayoutKind.explicit 对于本身是结构的字段的 .NET 行为

我尝试使用 构建一个 struct ( SA) [StructLayout(LayoutKind.Explicit)],它有一个字段是另一个struct( SB)。

首先:我很惊讶我被允许声明其他结构没有[StructLayout(LayoutKind.Explicit)],而在SA,所有字段都必须[FieldOffset(0)],否则编译器会大喊大叫。这没有多大意义。

  • 这是编译器警告/错误中的漏洞吗?

第二:似乎所有的 reference( object) 字段SB都移到了SB.

  • 这种行为在任何地方都有描述吗?
  • 它依赖于实现吗?
  • 它是否在任何依赖于实现的地方定义? :)

注意:我不打算在生产代码中使用它。我问这个问题主要是出于好奇。

实验

// No object fields in SB
// Gives the following layout (deduced from experimentation with the C# debugger):

// | f0 | f4 and i | f8 and j | f12 and k | f16 |

[StructLayout(LayoutKind.Explicit)]
struct SA …
Run Code Online (Sandbox Code Playgroud)

.net c# struct offset layoutkind.explicit

2
推荐指数
1
解决办法
3804
查看次数