我正在將單聲道嵌入到我正在創建的應用程序中,並且我沒有得到超遠,但我似乎無法找到的其中一件事是如何在使用對象和完成對象時告訴單聲道。嵌入式單聲道:在C++中保留對C#對象的引用
我想保留一個C#對象的引用來調用方法,直到它在C++中的並行對象的生命週期結束,此時,我想告訴mono,C#對象可以安全地收集。
這是如何完成的?
我正在將單聲道嵌入到我正在創建的應用程序中,並且我沒有得到超遠,但我似乎無法找到的其中一件事是如何在使用對象和完成對象時告訴單聲道。嵌入式單聲道:在C++中保留對C#對象的引用
我想保留一個C#對象的引用來調用方法,直到它在C++中的並行對象的生命週期結束,此時,我想告訴mono,C#對象可以安全地收集。
這是如何完成的?
看來我正在尋找的是mono_gchandle_new,並保留在句柄上,而不是MonoObject *,並在我需要時使用mono_gchandle_get_target。
mono_gchandle_new允許您在創建句柄時固定,但可以在事實之後固定嗎?
事實上你不能固定,但你可以創建一個新的,固定的gchandle。 –
好的呼叫。謝謝。 – Jeff
使用我遇到的mono_gchandle_new()時要記住的一件事情。它將只保留在內存中引用的C#對象,但是如果該對象分配其他對象,那些對象仍然受垃圾回收例程支配。事實上,你有一個對象的對象,可以讓你的子對象釋放你已經造成了我相當多的麻煩。
我目前正在挖掘單聲道GC系統,看看我是否可以修復它,因此它會將這些對象視爲根對象。
如果你有足夠的對象(< 4096),你可以使用mono_gc_register_root()...我們可以有成千上萬的對象,所以這對我們的使用沒有好處。
更新:所以我對此不正確,我們掛鉤了單聲道對象分配系統,並且沒有正確地將「原子」變量傳遞給GC分配函數。 「原子」意味着與GC不同的東西,它與併發訪問沒有任何關係,它實際上意味着內存被分配引用其他對象(原子= 0)或不原子(原子= 1)。
這很奇怪。微軟的版本,'clr :: gcroot',是'System :: GCHandle'的一個簡單包裝。 'System :: GCHandle'絕對作爲一個根,並保護所有直接或間接從它到達的對象。如果這不起作用,也許只是使用'System :: GCHandle'的數值? –
是的,這很奇怪..我們可能試圖以一種尚未真正使用過的方式使用單聲道。我用C++對象包裝了C#對象,並使用我們的內部反射系統從C++訪問單聲道數據。我認爲這是混淆了單聲道的GC系統,所以請在我的評論上面加上一點鹽。 –
使用System::GCHandle::Alloc
並在結果上調用ToIntPtr
以獲取令牌並保護對象不受收集。致電ToPointer()
,並將其存儲爲void*
。
當您需要將令牌映射到對象或釋放令牌時,使用System::GCHandle::FromIntPtr
以便它再次符合收集條件。
我知道微軟的.NET實現['gcroot'](http://msdn.microsoft.com/en-us/library/481fa11f(VS.80).aspx),但我不確定是否這對Mono來說是存在的。我懷疑這個託管到本地接口可能是可移植的。 –
我有同樣的問題,我通過在被分配對象的託管端有一個靜態字段來解決它,以便它永遠不會被收集。 –