简体   繁体   English

C#pinvoke封送处理工会

[英]C# pinvoke marshaling unions

I got some problems translating a C Union to C#. 将C Union转换为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];   
};

And here is one of my tries in C#: 这是我在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;
};

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)]? 这意味着它们不是全部都位于[FieldOffset(0)]吗?

Another headache is the last field varSzText . 另一个令人头疼的地方是varSzText的最后一个字段。 I got a sample C/C++ programm which uses this field as follows: printf("Text: %s\\n", &info.varSzText[0]); 我得到了一个使用此字段的示例C / C ++程序,如下所示: printf("Text: %s\\n", &info.varSzText[0]); My C isn't very good but if my interpretation is right, then char varSzText[8]; 我的C不太好,但是如果我的解释正确,那么char varSzText[8]; stores addresses to (\\0-terminated) strings. 将地址存储到(\\ 0终止)字符串中。 The sample program prints at least a 20-something character string. 该示例程序至少打印20位数的字符串。

  • Could somebody tell me, how to marshal this union? 有人可以告诉我,如何组织这个工会吗?
  • I googled and searched the forum before posting but mostly I found really simple unions with simple types (no arrays/strings). 在发布之前,我在论坛上进行了搜索和搜索,但是大多数情况下,我发现了具有简单类型(没有数组/字符串)的真正简单的联合。 Does anyone know a good read about pinvoke/marshaling? 有谁知道有关pinvoke /封送处理的很好的读物?

EDIT: 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. 因此,我将坚持使用Deduplicator的回答。 I'll create different structs for each field and parse the union according to the type-field. 我将为每个字段创建不同的结构,然后根据类型字段解析联合。

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). 您的问题是, union可以有很多东西,程序员可以在任何给定的时刻决定它的状态(最好不要搞砸它)。
As it is not tagged, there is no inherent way to decide. 由于没有标记,因此没有固有的决策方法。

So, the way to go is: 所以,要走的路是:

  1. Decide what option it is. 确定它是什么选项。
  2. Marshall accordingly. 马歇尔相应地。

(You might want to use a C++/CLI wrapper instead for flexibility in the more interesting cases.) (您可能想使用C ++ / CLI包装器,以便在更有趣的情况下保持灵活性。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM