Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#释放IntPtr引用的内存_C#_Pointers_Unmanaged - Fatal编程技术网

C#释放IntPtr引用的内存

C#释放IntPtr引用的内存,c#,pointers,unmanaged,C#,Pointers,Unmanaged,我正在使用一些非托管代码返回指向大型图像对象的指针(IntPtr)。我使用引用,但是在我完成图像之后,我需要释放指针引用的内存。目前,唯一能释放内存的就是关闭我的整个应用程序。我需要能够从我的应用程序中释放内存 下面是分配内存的调用hbitmap是返回并需要释放的指针 [DllImport("twain_32.dll", EntryPoint = "#1")] public static extern TwainResult DsImageTransfer( [In, Out] Iden

我正在使用一些非托管代码返回指向大型图像对象的指针(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);
您需要使用最初用于分配内存的特定内存分配器机制

因此,如果您使用COM和来分配内存,那么您必须在该实现上将返回传递给,以便释放分配的内存

[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);
如果您确实在使用调用返回的COM分配器,则可以在上调用

Marshal
类还有一个释放内存的方法,该方法是通过调用called来分配的

但是,这是一个常见的情况,如果内存被In C++分配,或者调用到C中,那么你必须通过互操作来公开非托管代码中的函数,这将适当地释放内存。

在C++的情况下,您将暴露一个函数,该函数接受一个指针并简单地调用该指针。在

malloc
的情况下,您将创建一个接受指针的函数,并调用该指针

关于您的问题,似乎
DsImageTransfer
是一个特定于供应商的API(我恐怕也是),因此需要更多关于特定API函数及其如何分配内存的信息。仅仅知道句柄类型(在本例中是一个)并不能给出如何分配它的任何指示。它可以与上面提到的所有机制一起分配


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

这取决于。您是否有任何关于您正在调用的本机函数的文档(或源代码)

本机代码没有单个释放函数。这是CLR的最大优点之一


如果我是个赌徒,我会去赌。但在代码停止崩溃之前,尝试各种API不会有多大乐趣。

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

已更新

如果我大胆猜测,您在twain_32.dll中调用的函数#1是twain提供程序中的DS#u ENTRY函数。调用内存资源管理协议:

TWAIN 2.0和 更高
TWAIN需要应用程序和 源来管理彼此的内存。 主要问题是保证 API使用协议。吐温 2.0引入了从源代码管理器获得的四个新函数 通过DAT_入口点

TW\u HANDLE PASCAL DSM\u MemAllocate(TW\u UINT32)

PASCAL DSM\u MemFree(TW\u句柄)

TW_MEMREF PASCAL DSM_MemLock(TW_句柄)

void PASCAL DSM\u MemUnlock(TW\u手柄)

这些功能对应于 WIN32全局内存函数 在以前版本的 TWAIN规范:
GlobalAlloc
GlobalFree
GlobalLock
GlobalUnlock

在MacOS/X上,这些函数调用
NewPtrClear
disposeptor
。锁 解锁功能不是ops,而是 他们仍然必须被叫来。吐温2.0 兼容的应用程序和源 必须在所有平台上使用这些调用 (Windows、MacOS/X和Linux)。这个 源代码管理器采用 确保所有 组件使用相同的内存 管理API

所以要释放资源,你应该称之为DSM_MemFree,它应该在Win32平台上通过或实现


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

请显示您的非托管代码。在非托管区域中分配内存有不同的方法,您必须使用正确的相应释放方法。您可能最终会实现一个终结器和IDisposable,并实现如下所述的Dispose模式:

也许您可以尝试从
hBitmap
创建一个
Bitmap
对象,然后对其进行处理

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

正如其他人所指出的,这取决于它是如何分配的。但是,如果它确实是一个Win32 hbitmap,那么您可以使用Win32“DeleteObject”函数将其解除分配。

内存是如何分配的?这是OK的副本,那么DsImageTransfer的文档说明了在您使用它时如何处理结果?如果你需要释放内存,他们必须告诉你怎么做。不幸的是,谷歌对DsImageTransfer的唯一结果就是这个问题。Bing没有发现任何结果。所以你仍然比我们更了解这个API@埃里克·利珀特:如果你已经确认它是重复的,那么你应该根据这些信息投票关闭它。您可以让rep执行此操作…如果本机释放系统是线程安全的,则只能从终结器调用本机释放函数。如果可能的话,最好避免写一个终结器。@厄尔维克:我没有考虑过非线程安全的交易——老实说,我没有想到有不安全的解除分配调用。事实上,在.Net中编写线程代码意味着什么(如果底层本机调用依赖于非线程