問題描述
我最近經(jīng)常使用鎖定位圖,并且不斷收到試圖訪問無效內(nèi)存"錯誤.這主要是因為位圖已在內(nèi)存中移動.有些人使用 GCHandle.Alloc()
在 CLR 中分配內(nèi)存并固定它.Bitmap.LockBits()
做同樣的事情嗎?我不明白鎖定"內(nèi)存和固定"內(nèi)存之間的區(qū)別.您能否解釋一下術(shù)語和差異(如果有)?
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
是一種更通用的方法,它允許您為任何托管對象分配一個句柄并將其固定在內(nèi)存中(或不).固定內(nèi)存可防止 GC 移動它,這在您必須將某些數(shù)據(jù)(例如數(shù)組)傳遞給非托管代碼時特別有用.
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
不會以任何方式幫助您訪問位圖的數(shù)據(jù),因為固定此對象只會阻止托管對象四處移動(位圖對象)(并被垃圾收集).
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+ 的 BITMAP
結(jié)構(gòu)的包裝.它不會將數(shù)據(jù)保存在您必須固定的任何托管數(shù)組中,它只是管理 GDI+ 位圖對象的本機(jī)句柄.因為 Bitmap.LockBits
是一種告訴這個位圖你有興趣訪問它的內(nèi)存的方式,它只是一個關(guān)于 GdipBitmapLockBits
函數(shù)的包裝器.因此,您需要調(diào)用它更多地與您使用 GDI+ 位圖的事實(shí)有關(guān),而不是與您在使用 GC 的托管環(huán)境中工作的事實(shí)有關(guān).
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
,您應(yīng)該能夠通過BitmapData.Scan0
使用指針訪問它的內(nèi)存——它是數(shù)據(jù)第一個字節(jié)的地址.只要您不訪問 BitmapData.Scan0 + Height * Stride
后面的內(nèi)存,您就不應(yīng)該有問題.
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
.
完成后記得UnlockBits
.
這篇關(guān)于Bitmap.LockBits 是否“固定"?位圖進(jìn)入內(nèi)存?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!