Marshal.OffsetOf 不反映运行时现实?
我想获取非托管结构中字段的偏移量。为此,我使用 Marshal.OffsetOf
方法,并且我意识到结果并不反映与 StructLayout
一起使用的 Packing
举个例子:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
unsafe public struct NETGROUP
{
public bool Advise;
public bool Active;
public int UpdateRate;
public double DeadBand;
}
namespace MyApp // Note: actual namespace depends on the project name.
{
internal class Program
{
static void Main(string[] args)
{
unsafe
{
// Technique 1 (not correct)
var oA = Marshal.OffsetOf(typeof(NETGROUP), "Advise").ToInt32();//0
var oB = Marshal.OffsetOf(typeof(NETGROUP), "Active").ToInt32();//4
var oC = Marshal.OffsetOf(typeof(NETGROUP), "UpdateRate").ToInt32();//8
var oD = Marshal.OffsetOf(typeof(NETGROUP), "DeadBand").ToInt32();//12
// Technique 2 (correct)
NETGROUP ex = new NETGROUP();
byte* addr = (byte*)&ex;
var oAa = (byte*)(&ex.Advise) - addr;//0
var oBb = (byte*)(&ex.Active) - addr;//1
var oCc = (byte*)(&ex.UpdateRate) - addr;//4
var oDd = (byte*)(&ex.DeadBand) - addr;//8
}
}
}
}
我需要在泛型中检索此偏移量构造函数,但第二种技术(这是正确的技术)不允许我在不明确指定类型的情况下实现它
public CMember(Type type, string pszName, CType pType, uint uMod = Modifier.TMOD_NON, int nDim = 0) : base(DefineConstants.TOKN_MBR)
{
m_sName = pszName;
m_nOffset = Marshal.OffsetOf(type, pszName).ToInt32(); // !!!
m_pType = pType;
m_uMod = uMod;
m_nDim = nDim;
}
你有想法吗?
I would like to get the offset of a field in an unmanaged structure. For this I use the Marshal.OffsetOf
method and I realized that the result does not reflect the Packing used with StructLayout
Take this example:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
unsafe public struct NETGROUP
{
public bool Advise;
public bool Active;
public int UpdateRate;
public double DeadBand;
}
namespace MyApp // Note: actual namespace depends on the project name.
{
internal class Program
{
static void Main(string[] args)
{
unsafe
{
// Technique 1 (not correct)
var oA = Marshal.OffsetOf(typeof(NETGROUP), "Advise").ToInt32();//0
var oB = Marshal.OffsetOf(typeof(NETGROUP), "Active").ToInt32();//4
var oC = Marshal.OffsetOf(typeof(NETGROUP), "UpdateRate").ToInt32();//8
var oD = Marshal.OffsetOf(typeof(NETGROUP), "DeadBand").ToInt32();//12
// Technique 2 (correct)
NETGROUP ex = new NETGROUP();
byte* addr = (byte*)&ex;
var oAa = (byte*)(&ex.Advise) - addr;//0
var oBb = (byte*)(&ex.Active) - addr;//1
var oCc = (byte*)(&ex.UpdateRate) - addr;//4
var oDd = (byte*)(&ex.DeadBand) - addr;//8
}
}
}
}
I need to retrieve this offset in a generic constructor but the second technique (which is the correct one) does not allow me to achieve it without specifying the type explicitly
public CMember(Type type, string pszName, CType pType, uint uMod = Modifier.TMOD_NON, int nDim = 0) : base(DefineConstants.TOKN_MBR)
{
m_sName = pszName;
m_nOffset = Marshal.OffsetOf(type, pszName).ToInt32(); // !!!
m_pType = pType;
m_uMod = uMod;
m_nDim = nDim;
}
Do you have an idea ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
OffsetOf 仅返回结构的非托管实例的布局
另请参见结构布局
“ex”是托管实例,因此您可以获得默认布局
The OffsetOf only returns the layout of the unmanaged instances of a struct
See also StructLayout
'ex' is a managed instance so you get the default layout
Marshal.OffsetOf
按预期工作,“问题”是System.Boolean
,它是 非 blittable 类型 且非托管大小为 4:来自
UnmanagedType
枚举文档:更改结构以包含
byte
字段而不是bool
字段会产生预期的输出:另一种方法是将
bool
编组为 <代码>UnmanagedType.I1:更多信息请参见此处。
Marshal.OffsetOf
is working as expected, the "issue" is theSystem.Boolean
which is a non-blittable type and has unmanaged size of 4:From
UnmanagedType
enum docs:Changing struct to contain
byte
fields instead ofbool
ones produces the expected output:Another approach is to marshal
bool
asUnmanagedType.I1
:Some more info here.