c# - 在 C# 上用 union 声明 C 结构

标签 c# c struct pinvoke unions

我想在我的代码中声明 _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 结构的 union 。

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

我们将不胜感激。

最佳答案

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

[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;
}

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

[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# 来定义类型。

关于c# - 在 C# 上用 union 声明 C 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34248749/

相关文章:

c# - 在设计时将数据绑定(bind)到 DataGrid

c - 从文件中读取多个实例

c - 在线程函数中取消引用结构数组?

c++ - 指向成员结构的指针如何工作?

c - 结构数组在声明时存储垃圾

C# - Unity3d MQTT - ArgumentException : Library compiled without SSL support

c# - 将 View 转换为分部 View

c - void * 和 void ** 之间的区别

C# 异常 - 使 "Source Error"成为调用该方法的行

c - OpenGL : error with invalid format but NULL data