这是我在
C
中的结构:
typedef struct s1 {
int i;
union {
s2 u1;
s3 u2;
}
}
typedef struct s2
{
int w[10];
}
typedef struct s3
{
int w[10];
}
这是我的 C# 代码:
public struct s2
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
int[] w;
}
public struct s3
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
int[] w;
}
[StructLayout(LayoutKind.Explicit)]
public struct s4
{
[FieldOffset(0)]
int i;
[FieldOffset(4)]
s2 s2;
[FieldOffset(4)]
s3 s3;
}
当我使用该结构时,它会抛出一个关于[偏移量 4 处的对象字段未正确对齐或与非对象字段重叠]的错误。
我用一个字节来保存这个地方,然后获取字节指针来转换s2或s3结构体;像这样[字节s3;]; 但用起来太糟糕了。
还有其他方法可以直接指定这个类型吗?
我不知道,我尝试添加属性
UnmanagedType.IUNknown
和其他一些,但它仍然不起作用
这里不能使用数组(引用类型);但是,内联数组(类似于“固定缓冲区”)可以很好地工作:
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Console.WriteLine(Unsafe.SizeOf<s4>());
// ^^^ 44 = 11 integers, as expected
var obj = new s4();
obj.s2[3] = 13;
Console.WriteLine(obj.s3[3]); // 13
[InlineArray(10)]
public struct s2
{
// this just defines the type for the inline array
private int w;
}
[InlineArray(10)]
public struct s3
{
// this just defines the type for the inline array
private int w;
}
[StructLayout(LayoutKind.Explicit)]
public struct s4
{
[FieldOffset(0)]
int i;
// changed accessibility to test
[FieldOffset(4)]
public s2 s2;
[FieldOffset(4)]
public s3 s3;
}
但是:老实说,鉴于
s2
和 s2
具有相同的形状......我真的不确定将它们作为单独的类型 is 在这里有什么意义。只要有单一类型和单一字段似乎就可以了。
如果您不使用 .NET 8 或更高版本;固定缓冲区:
public unsafe struct s2
{
private fixed int w[10];
public int this[int index]
{
get
{
fixed (int* ptr = w)
{
return new ReadOnlySpan<int>(ptr, 10)[index];
}
}
set
{
fixed (int* ptr = w)
{
new Span<int>(ptr, 10)[index] = value;
}
}
}
}
public unsafe struct s3
{
private fixed int w[10];
public int this[int index]
{
get
{
fixed (int* ptr = w)
{
return new ReadOnlySpan<int>(ptr, 10)[index];
}
}
set
{
fixed (int* ptr = w)
{
new Span<int>(ptr, 10)[index] = value;
}
}
}
}