c# – Windows 7 .NET 4.0中“Marshal.StructureToPtr”的访问冲
发布时间:2020-12-15 21:29:59 所属栏目:百科 来源:网络整理
导读:这是我的代码: internal void Show(){ if (Parent == null) throw new NullReferenceException(); EDITBALLOONTIP ebt = new EDITBALLOONTIP(); ebt.cbStruct = Marshal.SizeOf(ebt); ebt.pszText = Text; ebt.pszTitle = Caption; ebt.ttiIcon = (int)Icon
|
这是我的代码:
internal void Show()
{
if (Parent == null)
throw new NullReferenceException();
EDITBALLOONTIP ebt = new EDITBALLOONTIP();
ebt.cbStruct = Marshal.SizeOf(ebt);
ebt.pszText = Text;
ebt.pszTitle = Caption;
ebt.ttiIcon = (int)Icon;
IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ebt));
Marshal.StructureToPtr(ebt,ptrStruct,true); // Here we go.
// Access violation exception in Windows 7 + .NET 4.0
// In Windows XP + .NET 3.5,it works just fine.
// ... Some other code ...
Marshal.FreeHGlobal(ptrStruct);
}
这是结构: [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)]
private struct EDITBALLOONTIP
{
internal int cbStruct;
internal string pszTitle;
internal string pszText;
internal int ttiIcon;
}
为什么这在Windows XP .NET 3.5中运行良好并在Windows 7 .NET 4.0中引发异常?可能是CharSet有问题吗? =====================解决======================= 解决方案和解释 如你所见Marshal.StructureToPtr(ebt,true);将第三个参数设置为true.这意味着系统将尝试释放最后为ptrStruct分配的内存.但是当第一次调用方法Show()时,没有为该结构分配内存(ptrStruct = IntPtr.Zero).因此系统将尝试释放位于零指针的内存.当然它会引发异常. Windows XP只是忽略了这一点,但Windows 7却没有. 这是最好的解决方案恕我直言: Marshal.StructureToPtr(ebt,false); //Working... //Free resources Marshal.FreeHGlobal(ptrStruct); 解决方法
我不想在这里添加一个答案,因为你已经解决了你的问题,我会说不会对你所遇到的问题提供任何答案,但它不适合作为评论,因为我提供了一些代码.
所以我不得不在这里发布它作为答案. 您可能已经知道它(并且没有这样编写,因此您的问题中的代码更简单),但我只是想说,在分配非托管内存时应该在任何地方使用的最佳实践是封装代码在try / finally块中,以确保始终释放内存,即使抛出异常: private static void Test()
{
IntPtr ptrStruct = IntPtr.Zero;
try
{
Marshal.AllocHGlobal(0x100);
// Some code here
// At some point,an exception is thrown
throw new IndexOutOfRangeException();
}
finally
{
// Even if the exception is thrown and catch
// from the code that calls the Test() method,// the memory will be freed.
if (ptrStruct != IntPtr.Zero)
{
Marshal.FreeHGlobal(ptrStruct);
}
}
}
try
{
Test();
}
catch (IndexOutOfRangeException)
{
// Catches the exception,so the program won't crash
// but it'll exit the Test() method,so the try/finally
// ensures it won't leave without freeing the memory
Debugger.Break();
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
