是否Bitmap.LockBits"销"位图到内存中?位图、内存、Bitmap、LockBits

2023-09-03 05:14:10 作者:想的太多做的太少

我使用位图锁定了很多最近,我不断收到试图访问无效内存错误。这主要是因为该位图已经被移动到存储器中。使用 GCHandle.Alloc()有人在CLR分配内存和别起来。请问 Bitmap.LockBits()做?我不明白锁定存储器和钉住内存之间的区别。您也可以解释的术语和差异如果有的话?

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 是一个更通用的方法,可以让你的句柄分配给任何管理对象和引脚在内存中(或没有)。从移动它,这是特别有用的,当你必须通过一些数据,例如数组,以一个非托管code钢钉内存prevents GC。

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 不会帮助你访问的位图数据以任何方式,因为钉住该对象将只prevent管理对象从走动(位图对象)(和被垃圾收集)。

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).

位图不过是围绕机GDI +的位图结构的包装。它不留任何管理的阵列,你将不得不PIN数据,它只是管理的原生手柄GDI +位图对象。因为 Bitmap.LockBits 的一种方式告诉这个位图,你有兴趣访问它的内存,它只是一个围绕 GdipBitmapLockBits 功能。所以,你需要调用它的更多的是与您正在使用GDI +位图比的其实是你的工作在管理环境与GC的事实。

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.

一旦你使用 LockBits ,你应该能够通过 BitmapData.Scan0 来访问它的使用指针的内存 - 这是数据的第一字节的地址。你不应该有问题,只要,你不访问背后 BitmapData.Scan0 +高内存*步

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.

和rememberto UnlockBits ,当你做。

And rememberto UnlockBits when you are done.