C#释放IntPtr引用的内存

我正在使用一些非托管代码,它将指针(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); 

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

更新

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

TWAIN 2.0及更高版本的内存管理
TWAIN要求应用程序和源代码管理彼此的内存。 主要问题是保证就API的使用达成一致。 TWAIN 2.0引入了四个新function,这些function是从源管理器通过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)

这些函数对应于以前版本的TWAIN规范中提到的WIN32全局内存函数: GlobalAllocGlobalFreeGlobalLockGlobalUnlock
在MacOS / X上,这些函数调用NewPtrClearDisposePtr 。 锁定和解锁function是无操作,但仍然必须调用它们。 符合TWAIN 2.0的应用程序和源必须在所有平台(Windows,MacOS / X和Linux)上使用这些调用。 源管理器负责确保所有组件都使用相同的内存管理API。

因此,为了释放资源,您应该调用DSM_MemFree,据称在Win32平台上将通过GlobalFree或Marshal.FreeHGlobal实现 。

由于这主要是我的猜测,因此您最好使用您使用的特定TWAIN实现的规范进行validation。

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

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

如果您确实使用通过调用CoGetMalloc返回的COM分配器,则可以在Marshal类上调用静态FreeCoTaskMem方法 。

Marshal类还有一个释放内存的方法,该方法通过调用LocalAlloc称为FreeHGlobal

但是,这是一种常见的情况,如果内存是由C ++中的new运算符分配的,或者是C语言中对malloc的调用,则必须通过interop在非托管代码中公开一个函数,这将适当地释放内存。

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

在您的问题的具体方面,似乎DsImageTransfer是特定于供应商的API(我担心在网络上没有很多可发现性的 API),因此需要有关该特定API函数的更多信息以及如何它分配内存。 只知道句柄类型(在这种情况下是HBITMAP )并没有给出任何关于如何分配的指示。 它可以分配上面提到的所有机制。

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

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

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

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

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

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

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

正如其他人都指出的那样,它取决于它的分配方式。 但是,如果它确实是Win32 hbitmap,那么您可以使用Win32“DeleteObject”函数取消分配它。