清理非托管内存

时间:2009-08-31 14:46:57

标签: c# interop

每当我在Usercontrol中使用非托管dll中的一个函数时,我都会遇到此错误。 “System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”但只有在我多次使用此功能时才会发生这种情况。但是我需要每3分钟使用一次这个功能。非常感谢任何想法。谢谢。

2 个答案:

答案 0 :(得分:1)

根据您发布的信息非常少,我的第一个直觉响应是,如果由第三方编写的非托管dll在其中存在内存处理错误。如果它是一个包含的Windows DLL你需要做更多的研究如何使用它,或进入它使用的资源,因为这个错误很可能是由你的代码引起的,如果它是一个Windows DLL。

您应该研究的一件事是如何访问程序和外部DLL之间的共享数据,可能需要将某些成员标记为volatile并在处理时使用锁定。

答案 1 :(得分:0)

编组记忆管理是一件困难的事情。你提供的信息非常少,所以我只能回答:

Te Interop marshaller使用CoTaskMemFree和CoTaskMemAlloc来分配内存。如果您的DLL分配内存,并且.NEt应该释放它(反之亦然),您必须使用此功能。如果内存由new或malloc()分配并由delete或free()释放,则库必须提供一些Cleanup()函数来处理此问题。为了防止Marshaller释放内存,必须使用IntPtr将函数声明为参数/返回值数据类型,而不是使用字符串或其他任何内容。

考虑这个声明:

   [ DllImport( "Your.dll", CharSet=CharSet.Auto )]
   public static extern string GetSomeString();

   [ DllImport( "Your.dll", CharSet=CharSet.Auto )]
   public static extern IntPtr GetSomeString();

第一个函数必须返回一个用CoTaskMemAlloc()分配的字符串,并由.NET Marshaller释放。第二个函数可以返回malloc或delete分配的字符串,但不会自动释放内存。您必须调用某种类必须提供的FreeMemory(IntPtr)函数。

别忘了阅读: .NET Default Marshaling Behavior