可以使用UnmanagedMemory.LPTStr代替.byvaltstr导致内存损坏?为什么
本文关键字:内存 损坏 为什么 byvaltstr UnmanagedMemory LPTStr 代替 可以使 | 更新日期: 2023-09-27 18:01:42
我们在windows窗体应用程序中有一个树视图,使用以下代码使用适当的文件图标显示文件。我的问题是,调用GetIcon()似乎破坏了我的内存,因为我开始得到各种程序崩溃,我无法在此调用后用调试器捕获。当我将managedType.LPTStr
更改为managedType.ByValTStr
时,程序工作。这是一个真正的解决方案还是只是掩盖问题?
这段代码似乎在我们的上一个产品版本中工作,我看不出有任何变化。使用。net 4.0。我只在发布模式下看到问题。
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon=IntPtr.Zero;
iIcon=0;
dwAttributes=0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPTStr, SizeConst = 260)]//works if .ByValTStr is used instead
public string szDisplayName;
[MarshalAs(UnmanagedType.LPTStr, SizeConst = 80)]//works if .ByValTStr is used instead
public string szTypeName;
};
public static Icon GetIcon(string strPath, bool bSmall)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (bSmall)
flags = SHGFI.Icon|SHGFI.SmallIcon|SHGFI.UseFileAttributes;
else
flags = SHGFI.Icon|SHGFI.LargeIcon|SHGFI.UseFileAttributes;
SHGetFileInfo(strPath, 256, out info,(uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}
好吧,它不是一个适当的LPStr
结构,所以你不能试图封送它作为一个,并期望它的工作:
typedef struct _SHFILEINFO {
HICON hIcon;
int iIcon;
DWORD dwAttributes;
TCHAR szDisplayName[MAX_PATH];
TCHAR szTypeName[80];
} SHFILEINFO;
LPTStr
你使用当你已经分配了一个特殊的内存块只是为了保存这个字符串(通常在Marshal.AllocHGlobal
或类似),然后你已经复制了你的string
到非托管的内存区域。ByValTStr
,当你按值传递实际字符串时使用,而不是通过引用内存中的另一个区域。
结构体需要正确的值,而不是指针。
我知道这是一个老问题,但这帮助我解决了一个似乎突然开始频繁出现的崩溃。似乎是在。net 4.5.2更新通过Windows update推出后,我开始遇到这些问题。LPTStr
在更新之前工作,ByValTStr
在更新之后工作