使 StructLayout 在类上工作,因为它在结构上工作
Posted
技术标签:
【中文标题】使 StructLayout 在类上工作,因为它在结构上工作【英文标题】:Making a StructLayout over a class working as it works over a struct 【发布时间】:2015-11-10 07:39:30 【问题描述】:在处理非托管代码时,我想更好地理解结构/类的映射。
我定义了以下结构:
[StructLayout(LayoutKind.Sequential)]
public struct ProfileInfo
public int dwSize;
public int dwFlags;
[MarshalAs(UnmanagedType.LPTStr)] public string lpUserName;
[MarshalAs(UnmanagedType.LPTStr)] public string lpProfilePath;
[MarshalAs(UnmanagedType.LPTStr)] public string lpDefaultPath;
[MarshalAs(UnmanagedType.LPTStr)] public string lpServerName;
[MarshalAs(UnmanagedType.LPTStr)] public string lpPolicyPath;
public IntPtr hProfile;
public ProfileInfo(string userName, string profilepath)
dwFlags = 1;
dwSize = Marshal.SizeOf<ProfileInfo>();
lpUserName = userName;
lpServerName = null;
lpProfilePath = string.IsNullOrWhiteSpace(profilepath) ? null : profilepath;
lpPolicyPath = null;
lpDefaultPath = null;
hProfile = IntPtr.Zero;
与以下方法一起使用:
[DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LoadUserProfileW")]
public static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);
虽然只要ProfileInfo
是一个结构,它就可以很好地工作,但当我将ProfileInfo
设为一个类时,LoadUserProfile 开始失败。
我只是想知道为什么? 对我来说,StructLayout 以相同的方式应用于类或结构。
当我将其从 struct 更改为 class 时,导致 LoadUserProfile 失败的 ProfileInfo 的内存表示可能存在哪些差异?
【问题讨论】:
我的水晶球说您忘记从参数声明中删除ref
关键字。必需,因为类对象总是通过引用传递。在 SO 提出问题的最明智方法是发布不起作用的代码。
【参考方案1】:
在 C++ 中,类包含一个隐藏的“this”指针。我猜 C# 做同样的事情。
在下图中,pi 是一个结构体,p2 是一个类。您可以从内存转储中看到(左侧为 p,右侧为 p2),p2 有一些额外的字节,即隐藏指针。
【讨论】:
以上是关于使 StructLayout 在类上工作,因为它在结构上工作的主要内容,如果未能解决你的问题,请参考以下文章