我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 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/