将结构的C++并集转换为C#

本文关键字:转换 结构 C++ | 更新日期: 2023-09-27 18:26:43

我正试图使用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;
    }
}

当然,我不能在structs上使用FieldOffset或MarshalAs,但我不知道如何实现它。如果有人对如何在C#中实现这一点有一些想法,我将不胜感激

谢谢!

将结构的C++并集转换为C#

[FieldOffset]在结构字段上很好。但您的声明只是有嵌套类型(请注意,在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;
}

您当然可以使用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上的C++long是一个有符号的32位整数。这是C#中的int