2013-03-04 32 views
0

在不安全的環境中,我知道通過使用fixed聲明,我可以獲取並固定變量的地址,以便我可以安全地使用獲取的指針。但是,有什麼方法可以安全地將這個指針存儲在某個地方嗎?如在,使該變量永久固定,直到指針本身被處置。如何使一個變量永久固定在C#中?

例如,我應該怎麼做,如果我想的指針integer/float/double是我的不安全類的成員?爲牽制內存

+1

這是幹什麼用的?網絡?形式?你可以用代碼 – CR41G14 2013-03-04 11:47:42

+1

@ CR41G14更多地解釋你想要達到的目的嗎?這可能應該成爲問題的一部分,但標籤使它很清楚。 – JRoughan 2013-03-04 11:51:51

+0

以老式的方式分配這些對象可能是明智的,並使它們遠離託管視圖。固定託管對象會使垃圾收集器變得複雜,因此永久固定它們更加糟糕。 – hvd 2013-03-04 11:53:37

回答

10

更長久的解決辦法是使用GCHandle類,像這樣:

var handle = GCHandle.Create(myObject, GCHandleType.Pinned); 
IntPtr address = handle.AddrOfPinnedObject(); 
//... use it 
handle.Free(); 

這可以讓你獲取固定對象的地址,並防止GC從移動它。但是,你必須保持你的GCHandle活着,一旦你完成了就釋放它。這很容易跨越很多方法,甚至可以使用fixed()塊。

值得注意的是,固定內存可能會損害您的性能,因爲您正在使GC工作更難。

如果你需要一塊內存,它們不會移動,因爲你是用它來與間本地代碼等工作則可以考慮使用Marshal.AllocHGlobal()Marshal.FreeHGlobal(),這樣你就分配,不會干擾非移動存儲GC

+0

如果myObject(您在Create方法中的第一個參數)是值類型的,那麼獲得的地址是該對象的地址,還是將其作爲該對象的副本的地址?我怎樣才能通過IntPtr訪問底層對象?提前致謝。 – IcySnow 2013-03-04 12:16:46

+0

我不認爲myObject可以是一個值類型,如果你傳遞一個struct對象,它將被裝箱,因爲GCHandle接受一個對象參數。未定義的對象是什麼意思?你已經有了你的對象的引用,因爲你已經固定了它。但是,如果您確定課堂中的數據是如何佈局的,則可以通過獲取指針並將其移動一個偏移量來訪問它。例如,對於數組,當你從AddOfPinnedObject()得到一個指針時,它將指向第一個元素,所以你可以用這種方式使用指針訪問數組元素。 – 2013-03-04 12:23:49

+0

因此,如果我有一個已經分配的值類型變量,我不希望它被移動,我可以使用GCHandle來完成這項工作嗎? – IcySnow 2013-03-04 12:28:29