C#pinvoke封送处理工会

问题描述:

将C Union转换为C#时遇到了一些问题.这是联盟的定义:

I got some problems translating a C Union to C#. Here's the definition of the Union:

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

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

And here is one of my tries in 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)]吗?

I probably do everything wrong here. I read something about reference- and value types and that they are treated differently in the memory layout. Since most of the fields here are arrays, I guess, those are value types. Which means they are not all at [FieldOffset(0)]?

另一个麻烦的是最后一个字段varSzText. 我有一个示例C/C ++程序,它使用此字段,如下所示: printf("Text: %s\n", &info.varSzText[0]); 我的C不太好,但是如果我的解释正确,那么char varSzText[8];会将地址存储到(\ 0终止)字符串中.该示例程序至少会打印20多岁的字符串.

Another headache is the last field varSzText. I got a sample C/C++ programm which uses this field as follows: printf("Text: %s\n", &info.varSzText[0]); My C isn't very good but if my interpretation is right, then char varSzText[8]; stores addresses to (\0-terminated) strings. The sample program prints at least a 20-something character string.

  • 有人可以告诉我,如何组织这个工会吗?
  • 我在发布之前在论坛上进行了搜索和搜索,但大多数情况下,我发现了具有简单类型(没有数组/字符串)的真正简单的联合体.有人知道有关pinvoke/封送处理的很好的读物吗?

我发现,该联合仅在具有类型字段的结构中使用,该结构为我提供了有关联合中实际存储的内容的提示.因此,我将坚持使用Deduplicator的回答.我将为每个字段创建不同的结构,然后根据类型字段解析联合.

I found out, that the union is only used within a struct which has a type-field which gives me a hint on what is actually stored in the union. Therefore I'll stick with Deduplicator's answere. I'll create different structs for each field and parse the union according to the type-field.

您的问题是union可能有很多东西,程序员在任何给定的时刻都决定它是什么(最好不要弄乱它).
由于没有标签,因此没有固有的决策方法.

Your problem is that a union can be many things, and the programmer decides what it is in any given moment (and better not screw it up).
As it is not tagged, there is no inherent way to decide.

所以,要走的路是:

  1. 确定它是什么选项.
  2. 相应地,马歇尔.

(您可能想使用C ++/CLI包装器,以便在更有趣的情况下保持灵活性.)

(You might want to use a C++/CLI wrapper instead for flexibility in the more interesting cases.)