2010-06-29 61 views
5

在C#項目中,我需要通過將參考放入結構中來傳遞對象參數。 即我傳遞給調度員從void *轉換爲C#中的對象#

struct SOMESTRUCT 
{ 
    public int lpObject; 
} 

凡lpObject擁有像

class SomeClass 
{ 
    private string foo; 
} 

而且SOMESTRUCT結構從方法傳遞到方法,最終達到我的代碼一個指向自定義對象的結構。我不能修改的執行流程也不奇怪SOMSTRUCT系統,所以我猜唯一的解決辦法是我的對象轉換爲這樣的指針:

var myObject = new SomeClass(); 
GCHandle GC = GCHandle.Alloc(myObject, GCHandleType.Pinned); 
int myRef = GC.AddrOfPinnedObject().ToInt32(); 
GC.Free(); 

SOMESTRUCT struct; 
struct.lpObject = myRef; 
someMethod(struct); 

但是,我想不出如何檢索myObject的成員來自lpObject字段。像這樣的東西:

SomeClass myObject = CastPointerToObject(struct.myRef) as SomeClass; 

有沒有辦法做到這一點,或者它是不可能的?我如何告訴垃圾收集器處理對象?我應該創建一個新的垃圾收集對象並按字段複製數據字段?

TYIA,

+0

使用IntPtr而不是int ....所以它也能在64位下工作 – 2011-01-15 16:32:47

回答

4

否否否否!!!

struct SOMESTRUCT 
{ 
    public SomeClass object_ref; 
} 

是存儲在一個結構的引用的正確方法。

你寫的代碼和被接受的答案都被100%破壞了。

通過GC.AddrOfPinnedObject(GCHandle)返回的地址是唯一有效的,而GCHandle是否完好。您不能撥打GCHandle.Free,也不要讓GCHandle收集。在你的代碼中,這個地址在你存儲它的時候已經沒有意義了。

但是,您應該讓.NET在垃圾回收期間管理指針,方法是使用引用類型的變量。那麼你不需要跳過籃球。獲取託管對象地址的唯一原因是將它傳遞給現有的本機DLL函數,該函數將在返回後保存指針。例如,OpenGL緩衝區陣列是必需的。在調用其他C#方法時,這是不必要的。

如果SOMESTRUCT實際上是某種DLL函數使用的本機數據類型,您沒有提到,那麼您需要確保GCHandle保持活動狀態。只要GCHandle存在,您獲得的指針就會保持有效。

+0

同意。接受的答案是不正確的;但是我認爲對於我們不知道的故事還有更多的內容,否則,爲什麼運行時會正確管理編組的所有額外工作? – codekaizen 2011-01-15 17:21:29

+0

@codekaizen:是的,「SOMESTRUCT類型無法更改」的要求必須具備一些我們需要知道的基本原理,才能正確解決程序。 – 2011-01-15 17:30:24

+0

SOMESTRUCT類型是一個帶有「自定義指針」的窗口消息結構。這個指針最初用於(在程序中)引用包含序列化對象的字符串,這些對象工作得很好。在我的代碼中,有些類是不可序列化的,所以我不得不想出另一個解決方案。事實上,公認的解決方案看起來不錯,但從未經過測試,因爲它引發了更多的問題,所以我放棄了「指針/序列化」的東西,並採用了更多的C#方式來做事。 – slaphappy 2011-03-23 09:51:32

2

你的意思是你想要將返回的指針轉換回結構?

類似:

lvHitTestInfo = (LVHITTESTINFO)Marshal.PtrToStructure(lP, typeof(LVHITTESTINFO)); 

凡lvHitTestInfo是一個結構和LP的指針。

或者我沒有正確理解你的問題。也許你可以解釋更多(更完整的代碼示例)。

+0

是的,沒有。我想將返回的指針轉換爲對象。我會在我的問題中添加更多細節。 – slaphappy 2010-06-29 14:39:13

+0

我沒有注意到這種方法也適用於對象。這是我正在尋找的。感謝您的幫助 ! – slaphappy 2010-06-29 14:55:02

+0

我從來沒有去過那裏,但要知道如果這是可能的,你需要給出實際返回的確切描述。指針指向的是什麼。 請參閱,如果您正在與非託管代碼進行交互,那麼您將不可能投射到託管對象。沒有辦法知道什麼去了哪裏。 – Jeroen 2010-06-29 14:55:52