Yes, that will not work. When you use LayoutKind.Explicit , then the structure structure of the managed structure will be the one you specify. Just like an unmanaged version of the structure. In this particular case, however, this violates the .NET memory model. Which dictates that object references, such as ProcessEntry.ExeFile, are always atomic.
Atomization can only be achieved if the variable is correctly aligned. Thus, it can be updated with a single memory bus cycle. In 64-bit mode, the binding of an object link to 8 is required, since object references are 8-byte pointers. The problem is that offset 44 is only aligned to 4, not 8.
Not a problem in an unmanaged version of the structure in general, the ExeFile element is actually a WCHAR [] array. This requires only alignment by 2, so there is no need to type a block to get an element at 48.
You should discard LayoutKind.Explicit and use LayoutKind.Sequential instead. Light peasy can also make you feel good that your code is still working correctly in 32-bit mode.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct ProcessEntry { public int Size; public int Usage; public int ProcessId; public IntPtr DefaultHeapId; public int ModuleId; public int Threads; public int ParentProcessID; public int Priority; public int Flags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string ExeFile; }
And the check never hurts:
System.Diagnostics.Debug.Assert(IntPtr.Size == 8 && Marshal.OffsetOf(typeof(ProcessEntry), "ExeFile") == (IntPtr)44);
source share