64 Bit P/Invoke Idiosyncrasy

情到浓时终转凉″ 提交于 2020-01-15 04:18:06

问题


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.


回答1:


In a 64-bit C/C++ build the offset of your table field would be 8 due to alignment requirements (unless you forced it otherwise). I suspect that the CLR is doing the same to you:

  • http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx

The members of the object are laid out sequentially, in the order in which they appear when exported to unmanaged memory. The members are laid out according to the packing specified in StructLayoutAttribute.Pack, and can be noncontiguous.

you may wnat to use that attribute or use the LayoutKind.Explicit attribute along with the FieldOffset attribute on each field if you need that level of control.



来源:https://stackoverflow.com/questions/3903510/64-bit-p-invoke-idiosyncrasy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!