I am trying to properly Marshal some structs for a P/Invoke, but am finding strange behavior when testing on a 64 bit OS.
I have a struct defined as:
/// <summary>http://msdn.microsoft.com/en-us/library/aa366870(v=VS.85).aspx</summary>
[StructLayout(LayoutKind.Sequential)]
private struct MIB_IPNETTABLE
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwNumEntries;
public IntPtr table; //MIB_IPNETROW[]
}
Now, to get the address of the table, I would like to do a Marshal.OffsetOf() call like so:
IntPtr offset = Marshal.OffsetOf(typeof(MIB_IPNETTABLE), "table");
This should be 4 - I have dumped the bytes of the buffer to confirm this as well as replacing the above call with a hard coded 4 in my pointer arithmetic, which yielded correct results.
I do get the expected 4 if I instantiate MIB_IPNETTABLE and perform the following call:
IntPtr offset = (IntPtr)Marshal.SizeOf(ipNetTable.dwNumEntries);
Now, in a sequential struct the offset of a field should be sum of the sizes of preceding fields, correct? Or is it the case that when it is an unmanaged structure the offset really is 8 (on an x64 system), but becomes 4 only after Marshalling magic? Is there a way to get the OffsetOf() call to give me the correct offset? I can limp along using calls to SizeOf(), but OffsetOf() is simpler for larger structs.