【问题标题】:Declaring C struct with union on C#在 C# 上用 union 声明 C 结构
【发布时间】:2015-12-13 06:59:13
【问题描述】:

我想在我的代码中声明 _WAITCHAIN_NODE_INFO 结构声明 - 用于 WCT。 我尝试按照以下教程进行操作:

https://msdn.microsoft.com/en-us/library/eshywdt7(v=vs.110).aspx

但是每次我使用 WCT 调用和我的托管结构声明时都会遇到堆损坏。

typedef struct _WAITCHAIN_NODE_INFO {
  WCT_OBJECT_TYPE   ObjectType;
  WCT_OBJECT_STATUS ObjectStatus;
  union {
    struct {
      WCHAR         ObjectName[WCT_OBJNAME_LENGTH];
      LARGE_INTEGER Timeout;
      BOOL          Alertable;
    } LockObject;
    struct {
      DWORD ProcessId;
      DWORD ThreadId;
      DWORD WaitTime;
      DWORD ContextSwitches;
    } ThreadObject;
  };
} WAITCHAIN_NODE_INFO, *PWAITCHAIN_NODE_INFO;

MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681422(v=vs.85).aspx

唯一不会导致堆损坏的声明是:

public struct WAITCHAIN_NODE_INFO
{
    public WCT_OBJECT_TYPE ObjectType;
    public WCT_OBJECT_STATUS ObjectStatus;
}

显然,我在这里缺少 LockObject 和 ThreadObject 结构的联合。

如何将此 C 结构转换为 C# 托管声明?

任何帮助将不胜感激。

【问题讨论】:

标签: c# c struct pinvoke unions


【解决方案1】:

以通常的方式将联合中的两个结构声明为 C# 结构。然后使用显式布局为联合声明一个类型。

[StructLayout(LayoutKind.Explicit)] 
public struct _WAITCHAIN_NODE_INFO_UNION
{
    [FieldOffset(0)]
    _WAITCHAIN_NODE_INFO_LOCK_OBJECT LockObject;
    [FieldOffset(0)]
    _WAITCHAIN_NODE_INFO_THREAD_OBJECT ThreadObject;
}

然后将联合添加到您的结构中:

[StructLayout(LayoutKind.Sequential)]
public struct WAITCHAIN_NODE_INFO
{
    public WCT_OBJECT_TYPE ObjectType;
    public WCT_OBJECT_STATUS ObjectStatus;
    public _WAITCHAIN_NODE_INFO_UNION Union;
}

当您像这样叠加对象时,对所涉及的类型提出了额外的要求。例如,您不能覆盖包含字符串或数组的类型。所以字符数组必须实现为值类型,例如fixed array。这操作起来很不方便,但是 MS 没有考虑 C# 来定义类型。

【讨论】:

  • 当我尝试使用“_WAITCHAIN_NODE_INFO_UNION”时出现 TypeLoadException,这是错误:消息=无法从程序集“.....”加载类型“_WAITCHAIN_NODE_INFO_UNION”,因为它包含位于偏移量 8 未正确对齐或被非对象字段重叠。 :)
  • 您必须对字符串进行特殊处理。那需要是一个值类型。使其成为ushort 的固定数组。
  • 将对象名称更改为:public fixed ushort ObjectName[WctApiConst.WCT_OBJNAME_LENGTH];它有效。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-12-13
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多