我必须定义一个使用不安全代码的结构,所以我必须设置每个字段的 FieldOffset 值。但是我无法定义指针的大小。这是代码:
[StructLayout(LayoutKind.Explicit)]
public struct SomeStructO
{
public SomeStructO(int theNumber)
{
TheNumber = theNumber;
Coordinates = PointF.Empty;
SomeNumbers = null;
}
[FieldOffset(0)]
public PointF Coordinates;
[FieldOffset(sizeof(float) * 2)]
public int[] SomeNumbers;
[FieldOffset(sizeof(float) * 2 + IntPtr.Size)]
public int TheNumber;
}
给出错误,因为 IntPtr.Size 不是常量表达式当然,这个也不会编译:
Marshal.SizeOf(typeof(IntPtr))
当涉及到问题标题时,更多的是如何在 FieldOffset 定义中设置特定的"32 位 64 位编译"指针数据大小。
编辑:我也不能把"public int[] SomeNumbers;"字段放在结构的末尾,因为我的结构中有 2 个不同的数组.. 比如"public int[] SomeOtherNumbers;">
我最终在我的项目中放置了一个符号,并使用 int 和 long size 来声明指针大小
[StructLayout(LayoutKind.Explicit, Pack = 2)]
public struct VertexO
{
public VertexO(Vector location)
{
Location = location;
Neighbours = new IntListO();
Triangles = new IntListO();
}
public VertexO(float x, float y, float z) : this(new Vector(x, y, z)) { }
[FieldOffset(0)]
public Vector Location;
[FieldOffset(sizeof(float) * 3)]
public IntListO Neighbours;
#if WIN64
[FieldOffset(sizeof(float) * 3 + (sizeof(int) * 2 + sizeof(long)))]
#else
[FieldOffset(sizeof(float) * 3 + (sizeof(int) * 2 + sizeof(int)))]
#endif
public IntListO Triangles;
}
IntList 是另一个具有 2 个 int 和 1 个指针字段的结构:
[StructLayout(LayoutKind.Explicit, Pack = 2)]
public struct IntListO
{
//public IntListO()
//{
// Handle = IntPtr.Zero;
// FCount = 0;
// SizeOfItem = sizeOfItem;
// FCapacity = 0;
//}
private static int ItemSize = 4;//size of integer
[FieldOffset(0)]
private int FCount;
[FieldOffset(sizeof(int))]
private int FCapacity;
[FieldOffset(sizeof(int) * 2)]
private IntPtr Handle;
}
所以用
#if WIN64
[FieldOffset(sizeof(float) * 3 + (sizeof(int) * 2 + sizeof(long)))]
#else
[FieldOffset(sizeof(float) * 3 + (sizeof(int) * 2 + sizeof(int)))]
#endif
我实际上能够获得正确的指针大小。
顺便说一下,我使用"Pack = 2"来最合理地对齐字节。默认情况下它是 0,当我使用 Marshal.SizeOf(typeof(VertexO((时,它增加了额外的大小,并且我用一些顶点和三角形测试进行了测试,它工作得很好。
谢谢你们
使用不安全的代码,所以我必须设置每个 领域
为什么需要为每个字段指定字段偏移量? 如果在 StructLayout 属性中使用 LayoutKind.Sequential 和适当的 Pack 大小,则不需要像尝试使用 LayoutKind.Explicit 那样指定确切的 FieldOffset 。
像这样的东西可能是你想要的:
[StructLayout(LayoutKind.Sequential)]
public struct SomeStructO
{
public SomeStructO(int theNumber)
{
TheNumber = theNumber;
Coordinates = PointF.Empty;
SomeNumbers = null;
}
public PointF Coordinates;
[MarshalAs(UnmanagedType.LPArray)]
public int[] SomeNumbers;
public int TheNumber;
}