2015-11-19 28 views
2

如果我有一個像將c#中的類編組爲本地C++時,它會克隆嗎?

[DllImport("SomeDll")] 
private static extern void passAClass(ClassType myClass); 

C#代碼,並調用它像

ClassType myClass = new ClassType(); 
passAClass(myClass); 

我可以看到類(其數據段)被傳遞到DLL爲指針,但我不是確定運行時是否將類數據從其位置複製到新內存中,然後將指針傳遞到該新內存,或者是否將指針直接傳遞到類的內存位置。

我可以看到,如果dll更改內存中的數據,它將接收到一個指針,該調用在調用後在c#中可見,但這可能是因爲它將另一個內存副本重新放回到託管位置類存儲。

+0

我認爲當你編組實例時,只是傳遞足夠的信息來展示對象應該如何交互以及它的結構是什麼樣的 - 數據+元數據+定義的位置。基於此,我認爲除了如何處理數據的結構之外,傳遞的實際對象只是一個引用,以便遠程進行的更改確實會更改對象的數據。不是100%。 –

+0

這是該類實例的要點。要小心,因爲該類可能包含指向實際數據的指針。例如,類中的數組是一個指針,並且該點的大小可能因數組是本地還是全局而不同。該數組應該是靜態的,以便可以通過dll訪問。 – jdweng

回答

1

但可能是因爲它的內存又複製回

不,這不是自動的,你明確地必須給[OUT]屬性,以確保參數,它複製回。您確實看到沒有屬性的變化,證明該類是blittable。換句話說,類的字段都是簡單的值類型,並且它們沒有被CLR重新排列。因此,託管佈局與非託管佈局相同,允許pinvoke編組綁定對象並傳遞指針。

這並不罕見。最好不要讓它成爲一個意外事件,例如,當你將本地代碼移植到x64時,你可能會在下雨天失去一天。給這個類[StructLayout]屬性確保順序佈局是一個好主意。

+0

我應該提到,在實際使用我_do_使用structLayout順序(雖然我認爲它是實際的默認值?) 我讀你的答案,以確認一個副本不是爲簡單的類型,所以如果傳遞的類是一個巨大的數組只會固定它並傳遞指針,而不是昂貴地複製數組兩次? 什麼是一個非blittable參數的情況?引用另一個類c2的類c1,其中只有c1的數據被傳遞,包含一個無用的指向c2的指針? – JoeTaicoon