我正在尝试使用C#来使用包含一个结构的C ++库,该结构被记录为如下所示:
struct {
long outervar;
long othervar;
union {
struct {
long a;
} firststruct;
struct {
long p;
long q;
long r;
long s;
} secondstruct;
struct {
long x;
long y;
long z;
} thirdstruct;
} myunion;
} outerstruct;
理想情况下,我想实现类似的东西:
struct outerstruct
{
UInt32 outervar;
UInt32 othervar;
[FieldOffset(0)]
struct firststruct
{
UInt32 a;
}
[FieldOffset(0)]
struct secondstruct
{
UInt32 p;
UInt32 q;
UInt32 r;
UInt32 s;
}
[FieldOffset(0)]
struct thirdstruct
{
UInt32 x;
UInt32 y;
UInt32 z;
}
}
当然我不能在结构上使用FieldOffset或MarshalAs,但我不知道如何实现它。如果有人有一些想法如何在C#中实现这一点我会很感激。
谢谢!
答案 0 :(得分:2)
[FieldOffset]在struct 字段上没问题。但是你的声明只有嵌套类型(请注意,在C ++代码中,结构实际上是匿名的,但用于声明一个新字段......你的C#代码只声明了一个名为结构,但没有实际领域)。请注意,您还需要包含[StructLayout(LayoutKind.Explicit)],并为结构中的所有字段提供偏移量。
尝试这样的事情:
struct firststruct
{
UInt32 a;
}
struct secondstruct
{
UInt32 p;
UInt32 q;
UInt32 r;
UInt32 s;
}
struct thirdstruct
{
UInt32 x;
UInt32 y;
UInt32 z;
}
[StructLayout(LayoutKind.Explicit)]
struct union
{
[FieldOffset(0)]
firststruct firststruct;
[FieldOffset(0)]
secondstruct secondstruct;
[FieldOffset(0)]
thirdstruct thirdstruct;
}
struct outerstruct
{
UInt32 outervar;
UInt32 othervar;
union union;
}
答案 1 :(得分:1)
你当然可以使用FieldOffset
,这就是答案。但是你需要将联合定义为一种独特的类型。
以通常的方式定义每个结构。我会假设你知道如何做到这一点。
然后定义联合:
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public FirstStruct firststruct;
[FieldOffset(0)]
public SecondStruct secondstruct;
[FieldOffset(0)]
public ThirdStruct thirdstruct;
}
最后把它们放在一起:
[StructLayout(LayoutKind.Sequential)]
public struct OuterStruct
{
public int outervar;
public int othervar;
public MyUnion myunion;
}
关键是始终使联合成为一种不同的类型,并为每个成员使用零字段偏移量。
Windows上的FWIW,C ++ long
是带符号的32位整数。那是C#中的int
。