C# pinvoke 封送处理联合

本文关键字:处理 pinvoke | 更新日期: 2023-09-27 18:30:59

我在将 C 联盟转换为 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 多个字符串。

  • 有人能告诉我,如何组织这个工会吗?
  • 我在发布之前用谷歌搜索了论坛,但大多数情况下,我发现了非常简单的联合,类型简单(没有数组/字符串)。有谁知道关于 pinvoke/封送处理的好读物吗?

编辑:我发现,联合只在一个结构中使用,该结构有一个类型字段,这给了我一个关于联合中实际存储的内容的提示。因此,我将坚持使用重复数据删除器的答案。我将为每个字段创建不同的结构,并根据类型字段解析联合。

C# pinvoke 封送处理联合

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

所以,要走的路是:

  1. 确定它是什么选项。
  2. 马歇尔因此。

(您可能希望改用 C++/CLI 包装器,以便在更有趣的情况下实现灵活性。