c# - Bitmap.LockBits "pin"位图是否存入内存?

标签 c# .net memory bitmap lockbits

我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 GCHandle.Alloc() 在 CLR 中分配内存并固定它。 Bitmap.LockBits() 做同样的事情吗?我不明白“锁定”内存和“固定”内存之间的区别。您能否也解释一下术语和差异(如果有)?

最佳答案

GCHandle.Alloc 是一种更通用的方法,它允许您为任何托管对象分配句柄并将其固定在内存中(或不固定)。固定内存可防止 GC 移动它,这在您必须将某些数据(例如数组)传递给非托管代码时特别有用。

GCHandle.Alloc 不会帮助您以任何方式访问位图的数据,因为固定此对象只会阻止托管对象四处移动(Bitmap 对象)(并被垃圾收集)。

然而,位图是对 native GDI+ 的 BITMAP 结构的包装。它不会将数据保存在您必须固定的任何托管数组中,它只是管理 GDI+ 位图对象的 native 句柄。因为 Bitmap.LockBits 是一种告诉此位图您有兴趣访问它的内存的方式,它只是 GdipBitmapLockBits 函数的包装器。因此,您需要调用它更多地是因为您正在使用 GDI+ 位图,而不是因为您正在使用 GC 在托管环境中工作。

一旦您使用了 LockBits,您应该能够使用指针通过 BitmapData.Scan0 访问它的内存 - 它是数据第一个字节的地址。只要您不访问 BitmapData.Scan0 + Height * Stride 后面的内存,您就不会有问题。

完成后记得UnlockBits

关于c# - Bitmap.LockBits "pin"位图是否存入内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26848728/

相关文章:

c# - C# 中的连接登记到底是什么

c# - 在 Linq 查询中检查对象是否为 Null

c++ - vector C++ 内存分配

C++:从函数返回类对象

c# - 将 Python re.sub 转换为 C#

c# - 从 HttpResponseMessage.Content 读取流式内容

c# - 属性描述符如何使用相同的代码行获取两个控件的值?

.net - Fusion Log Viewer 的替代品?

.net - 为什么 Visual-Studio 开发服务器会自动分配端口号?

memory - 在 MIPS Assembly 中,为什么保存和恢复程序需要使用的已保存寄存器很重要?