Dav*_*ave 10 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);
Run Code Online (Sandbox Code Playgroud)
您需要使用首先用于分配内存的特定内存分配器机制.
因此,如果您使用COM和IMalloc
接口来分配内存,那么您必须将IntPtr
后端传递给该实现上的Free
方法以释放分配的内存.
如果您确实使用了调用返回的COM分配器CoGetMalloc
,那么您可以在类上调用静态FreeCoTaskMem
方法.Marshal
该Marshal
班也有释放是通过调用分配内存的方法LocalAlloc
叫FreeHGlobal
.
但是,这是一种常见的情况,如果内存是由new
运算符在C++中分配的,或者是malloc
在C中的调用,那么你必须通过interop在非托管代码中公开一个函数,这将适当地释放内存.
在C++的情况下,您将公开一个带有指针的函数,并简单地调用delete
该指针.在这种情况下malloc
,您将创建一个带有指针的函数,并调用free
该指针.
在您的问题的具体方面,它似乎DsImageTransfer
是特定于供应商的API(我担心在网络上没有很多可发现性的 API ),因此需要有关该特定API函数的更多信息以及它如何分配内存.只知道句柄类型(HBITMAP
在这种情况下)并没有给出如何分配它的任何指示.它可以分配上面提到的所有机制.
假设它正在创建HBITMAP
使用GDI Object api函数(特别是CreateBitmap
函数),那么您可以使用该DeleteObject
函数来释放句柄(根据GDI Object API函数的文档页面).
这取决于内存的分配方式。Marshal类具有用于释放通过常见互操作分配模式分配的内存的方法,例如FreeCoTaskMem。如果非托管代码使用非互操作兼容的分配方式,则您无法与其进行互操作。
\n\n更新
\n\n如果我大胆猜测一下,您在 twain_32.dll 中调用的函数 #1 是 TWAIN 提供程序中的 DS_ENTRY 函数。吐温规格调用了内存资源管理协议:
\n\n\n\n\nTWAIN 2.0 及\n更高版本中的内存管理
\n\n
\n TWAIN 要求应用程序和\n 源相互管理\xe2\x80\x99s 内存。\n 主要问题是保证\n API 上的一致\xe2\x80\x99s使用。TWAIN\n 2.0 引入了四个新函数,这些函数可通过 DAT_ENTRYPOINT 从源管理器\n 获取。\n\n
TW_HANDLE PASCAL DSM_MemAllocate (TW_UINT32)
\nPASCAL DSM_MemFree (TW_HANDLE)
\nTW_MEMREF PASCAL DSM_MemLock(TW_HANDLE)
\nvoid PASCAL DSM_MemUnlock(TW_HANDLE)
这些函数对应于\n TWAIN 规范的早期版本中提到的\n WIN32 全局内存函数\n:
\nGlobalAlloc
,\nGlobalFree
,GlobalLock
,GlobalUnlock
\n 在 MacOS/X 上,这些函数调用\nNewPtrClear
和DisposePtr
。锁定和解锁函数是无操作的,但仍然必须调用它们。符合 TWAIN 2.0\n 标准的应用程序和源\n 必须在所有平台\n(Windows、MacOS/X 和 Linux)上使用这些调用。源管理器负责确保所有组件都使用相同的内存管理 API\xe2\x80\x99。
因此,要释放资源,您应该调用 DSM_MemFree,据说在 Win32 平台上将通过GlobalFree或Marshal.FreeHGlobal实现实现。
\n\n由于这主要是我的猜测,因此您最好使用您使用的特定 TWAIN 实现的规范进行验证。
\n