1

I want to declare _WAITCHAIN_NODE_INFO struct declaration in my code - for WCT usage. I've tried to follow the tutorials from :

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

But every time then I use WCT call with my managed struct declaration I get heap corruption.

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

The only declaration that doesn't get me a heap corruption is this:

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

Obviously, I am missing here the union of LockObject and ThreadObject structs.

How can I convert this C struct to C# managed declaration?

Any help will be appreciated.

timrau
  • 22,578
  • 4
  • 51
  • 64
Pavel Durov
  • 1,287
  • 2
  • 13
  • 28
  • 1
    Not sure why you got downvoted, but does this help you on your way? http://stackoverflow.com/questions/126781/c-union-in-c-sharp – bas Dec 13 '15 at 07:05
  • Although c++ is long forgotten for me but these link might help you :http://stackoverflow.com/questions/34139351/wct-getthreadwaitchain-call-allways-return-false & http://stackoverflow.com/questions/34020727/calling-c-method-from-c-sharp-with-pointer-parameter-wct – Vinod Srivastav Dec 13 '15 at 09:23

1 Answers1

3

Declare the two structs in the union as C# structs in the usual way. Then declare a type for the union, using an explicit layout.

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

Then add the union to your struct:

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

When you overlay objects like this, extra requirements are placed on the types involved. You cannot overlay a type containing a string or an array for instance. So the character array will have to be implemented as a value type, for instance a fixed array. This is inconvenient to operate with but MS did not define the types with C# in mind.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I get TypeLoadException as I am trying to use '_WAITCHAIN_NODE_INFO_UNION' this is the error: Message=Could not load type '_WAITCHAIN_NODE_INFO_UNION' from assembly '.....' because it contains an object field at offset 8 that is incorrectly aligned or overlapped by a non-object field. :) – Pavel Durov Dec 13 '15 at 08:14
  • 1
    You'll have to give special handling to the string. That needs to be a value type. Make it a fixed array of `ushort`. – David Heffernan Dec 13 '15 at 08:19
  • changed the Object name to: public fixed ushort ObjectName[WctApiConst.WCT_OBJNAME_LENGTH]; and it works. Thanks! – Pavel Durov Dec 13 '15 at 11:54