C#释放IntPtr引用的内存

时间:2010-02-19 21:00:42

标签: c# pointers unmanaged

我正在使用一些非托管代码,它将指针(IntPtr)返回给大图像对象。我使用引用但在完成图像后,我需要释放指针引用的内存。目前,唯一释放内存的是关闭我的整个应用程序。我需要能够从我的应用程序中释放内存。

这是对内存的分配。 hbitmap是返回的指针,需要取消分配。

[DllImport("twain_32.dll", EntryPoint = "#1")]
public static extern TwainResult DsImageTransfer(
    [In, Out] Identity origin, [In] Identity dest, DataGroup dg, 
    DataArgumentType dat, Message msg, ref IntPtr hbitmap);

6 个答案:

答案 0 :(得分:8)

您需要使用首先用于分配内存的特定内存分配器机制。

因此,如果您使用COM和IMalloc interface来分配内存,那么您必须将IntPtr传递回该实现上的Free method以释放内存分配

如果您确实使用了通过CoGetMalloc调用返回的COM分配器,那么您可以拨打static FreeCoTaskMem method上的Marshal class

Marshal类还有一种释放内存的方法,该内存通过调用名为LocalAllocFreeHGlobal分配。

但是,这是一种常见的情况,如果内存是由C ++中的new operator分配的,或者是C中对malloc的调用,则必须通过非托管代码公开函数互操作,将适当地释放记忆。

对于C ++,您将公开一个带有指针的函数,并简单地在该指针上调用delete。在malloc的情况下,您将创建一个带有指针的函数,并在该指针上调用free

就您的问题而言,DsImageTransfer似乎是供应商特定的API(我担心doesn't have much discoverability on the web也是如此),因此需要有关该特定API的更多信息功能以及它如何分配内存。只知道句柄类型(在这种情况下是HBITMAP)并没有给出任何关于它如何分配的指示。它可以分配上面提到的所有机制。

假设它正在使用GDI Object api functions(特别是CreateBitmap function)创建HBITMAP,那么您可以使用DeleteObject function来释放句柄(根据文档页面)对于GDI Object API函数)。

答案 1 :(得分:4)

这取决于内存的分配方式。 Marshal类具有释放通过公共互操作分配模式分配的内存的方法,如FreeCoTaskMem。如果非托管代码使用非Interop兼容的分配方式,则无法与其互操作。

<强>更新

如果我冒昧猜测,你在twain_32.dll中调用的函数#1是TWAIN提供程序中的DS_ENTRY函数。 Twain specifications调出内存资源管理协议:

  

TWAIN 2.0和Linux中的内存管理   更高
  TWAIN需要应用程序和   管理彼此记忆的来源。   主要问题是保证   关于API的使用协议。 TWAIN   2.0介绍了从源管理器获得的四个新功能   通过DAT_ENTRYPOINT。

     

TW_HANDLE PASCAL DSM_MemAllocate (TW_UINT32)
  PASCAL DSM_MemFree (TW_HANDLE)
  TW_MEMREF PASCAL DSM_MemLock(TW_HANDLE)
  void PASCAL DSM_MemUnlock(TW_HANDLE)

     

这些功能对应于   WIN32全局内存功能   在之前的版本中提到过   TWAIN规范:GlobalAlloc,   GlobalFreeGlobalLockGlobalUnlock
  在MacOS / X上,这些函数调用   NewPtrClearDisposePtr。锁   和解锁功能是无操作的,但是   他们仍然必须被召唤。 TWAIN 2.0   合规的应用程序和来源   必须在所有平台上使用这些调用   (Windows,MacOS / X和Linux)。该   Source Manager接受了   有责任确保所有   组件使用相同的内存   管理API。

所以要释放资源,你应该调用DSM_MemFree,据说在Win32平台上可以通过GlobalFreeMarshal.FreeHGlobal来实现。

由于这主要是我的推测,您最好使用您使用的特定TWAIN实现的规范进行验证。

答案 2 :(得分:2)

这取决于。您有所调用的本机函数的文档(或源代码)吗?

本机代码没有单个释放功能。这是CLR的一大优势。

如果我是博彩人,我会去GlobalFree。但是,在代码停止崩溃之前尝试各种API并不会很有趣。

答案 3 :(得分:2)

请显示您的非托管代码。在非托管域中分配内存有不同的方法,您必须使用正确的相应解除分配方法。您可能最终会实现Finalizer和IDisposable,并按照此处所述实现Dispose模式:http://www.codeproject.com/KB/cs/idisposable.aspx

答案 4 :(得分:0)

也许你可以尝试从Bitmap创建一个hBitmap对象,然后将其处理掉。

Bitmap bitmap = Bitmap.FromHBitmap(hBitmap);
bitmap.Dispose();

答案 5 :(得分:0)

正如其他人都指出的那样,这取决于它的分配方式。但是,如果它确实是Win32 hbitmap,那么您可以使用Win32“删除对象”功能取消分配它。