作者:Remember_Mi | 来源:互联网 | 2023-05-18 17:00
Imusinglockedbitmapsalotrecently,andIkeepgettingattemptedtoaccessinvalidmemoryerr
I'm using locked bitmaps a lot recently, and I keep getting "attempted to access invalid memory" errors. This is mostly because the bitmap has been moved in memory. Some people using GCHandle.Alloc()
to allocate memory in the CLR and pin it. Does Bitmap.LockBits()
do the same? I don't understand the difference between "locking" memory and "pinning" memory. Can you also explain the terminology and the differences if any?
我最近使用锁定的位图,并且一直“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用GCHandle.Alloc()在CLR中分配内存并固定它。 Bitmap.LockBits()也这样做吗?我不明白“锁定”内存和“固定”内存之间的区别。你能解释术语和差异吗?
2 个解决方案
8
GCHandle.Alloc
is a more generic method, that allows you to allocate a handle to any managed object and pin it in memory (or not). Pinning memory prevents GC from moving it around, which is especially useful when you have to pass some data, for example an array, to a unmanaged code.
GCHandle.Alloc是一种更通用的方法,允许您为任何托管对象分配句柄并将其固定在内存中(或不固定)。固定内存会阻止GC移动它,这在您必须将某些数据(例如数组)传递给非托管代码时尤其有用。
GCHandle.Alloc
will not help you access bitmap's data in any way, because pinning this object will just prevent the managed object from moving around (the Bitmap object) (and being garbage collected).
GCHandle.Alloc不会以任何方式帮助您访问位图的数据,因为固定此对象只会阻止托管对象移动(Bitmap对象)(并进行垃圾回收)。
Bitmap however is a wrapper around native GDI+'s BITMAP
structure. It doesn't keep data in any managed array that you would have to pin, it just managed a native handle to GDI+ bitmap object. Because of that Bitmap.LockBits
is a way of telling this bitmap that you are interested in accessing it's memory, and it's just a wrapper around GdipBitmapLockBits
function. So your need of calling it has more to do with the fact that you are working with GDI+ bitmaps than with the fact, that you're working in managed environment with GC.
然而,Bitmap是本机GDI +的BITMAP结构的包装器。它不会将数据保存在您必须固定的任何托管数组中,它只是管理了GDI +位图对象的本机句柄。因为Bitmap.LockBits是一种告诉这个位图的方式,你有兴趣访问它的内存,它只是GdipBitmapLockBits函数的包装器。因此,您需要调用它更多地与您使用GDI +位图这一事实有关,而不是与您在使用GC的托管环境中工作的事实有关。
Once you have used LockBits
you should be able to access it's memory using pointers through BitmapData.Scan0
- it's an address of first byte of data. You should not have problems as long, as you do not access memory behind BitmapData.Scan0 + Height * Stride
.
一旦你使用了LockBits,你应该能够通过BitmapData.Scan0使用指针访问它的内存 - 它是数据第一个字节的地址。你应该没有问题,因为你没有访问BitmapData.Scan0 + Height * Stride后面的内存。
And rememberto UnlockBits
when you are done.
当你完成时,记得UnlockBits。