C#pinvoke marshaling工会

时间:2014-11-19 02:24:51

标签: c# pinvoke marshalling

我在将C Union转换为C#时遇到了一些问题。以下是联盟的定义:

union Info
{
    char        varChar[8];
    short       varShort[4];
    int         varInteger[2];
    float       varFloat[2];
    double      varDouble;
    __int64     varInteger64;
    char        varSzText[8];   
};

这是我在C#中的一次尝试:

[StructLayout(LayoutKind.Explicit)]
public struct Info
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string varChar;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I2, SizeConst = 4)]
    public short[] varShort;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I4, SizeConst = 2)]
    public int[] varInteger;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R4, SizeConst = 2)]
    public float[] varFloat;

    [FieldOffset(0)]
    public double varDouble;

    [FieldOffset(0)]
    public long varInteger64;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStr, SizeConst = 8)]    //LPStr, LPWStr, BStr oder LPTStr 
    public string[] varSzText;
};

我可能在这里做错了。我读了一些关于引用和值类型的内容,并且它们在内存布局中的处理方式不同。由于这里的大多数字段都是数组,我想这些是值类型。这意味着它们并非都在[FieldOffset(0)]?

另一个难题是最后一个字段varSzText。 我得到了一个示例C / C ++程序,它使用如下字段: printf("Text: %s\n", &info.varSzText[0]); 我的C不是很好,但如果我的解释是正确的,那么char varSzText[8];将地址存储到(\ 0-终止的)字符串。示例程序打印至少20个字符的字符串。

  • 有人可以告诉我,如何组织这个联盟?
  • 我在发布之前用Google搜索并搜索了论坛,但大多数时候我发现了非常简单的类型(没有数组/字符串)的简单联合。有没有人知道关于pinvoke / marshaling的好读物?

修改 我发现,union只在一个结构中使用,该结构有一个类型字段,它给出了一个关于实际存储在union中的内容的提示。因此,我会坚持使用Deduplicator的回答。我将为每个字段创建不同的结构,并根据类型字段解析联合。

1 个答案:

答案 0 :(得分:0)

你的问题是union可以是很多东西,程序员在任何特定时刻决定它是什么(最好不要搞砸了)。
由于没有标记,因此没有固有的决定方法。

所以,要走的路是:

  1. 决定它是什么选项。
  2. 马歇尔。
  3. (您可能希望使用C ++ / CLI包装器来获得更有趣的案例的灵活性。)