2010-09-02 50 views
9

我的直覺反應是否定的,因爲託管和非託管內存是不同的,但我不確定.NET Framework是否正在幕後進行一些操作。C#中的結構修改會影響非託管內存嗎?

我相信發生的情況是: 當正從我的非託管的DLL一個結構,它是一樣的作出這一呼籲得到一個IntPtr,然後使用它和Marshal類的結構複製到託管內存(和作出的到託管內存中的結構不會冒泡)。

我似乎無法在MSDN上的任何位置找到此文檔。任何鏈接將不勝感激。

這裏是我的代碼如下所示:

[DllImport("mydll.dll", BestFitMapping=false, CharSet=CharSet.Ansi)] 
private static extern int GetStruct(ref MyStruct s); 

[StructLayout(LayoutKind.Sequential, Pack=0)] 
struct MyStruct 
{ 
    public int Field1; 
    public IntPtr Field2; 
} 

public void DoSomething() 
{ 
     MyStruct s = new MyStruct(); 
     GetStruct(ref s); 

     s.Field1 = 100; //does unmanaged memory now have 100 in Field1 as well? 
     s.Field2 = IntPtr.Zero; //does unmanaged memory now have a NULL pointer in field Field2 as well? 
} 

回答

0

CSharp語言Specification.doc第26頁

結構構造函數調用與新的運營商,但是,這並不意味着內存被分配。結構構造器不是動態分配對象並返回對象的引用,而是簡單地返回結構值本身(通常位於堆棧上的臨時位置),然後根據需要複製該值。

因爲,'struct'後備存儲沒有什麼特別之處,所以不會指望在成員分配後面進行匿名編組操作。

+0

我認爲這是正確的答案。事實上,沒有任何東西掛鉤到結構(或其字段)中,以便在其字段更改時將其更改回非託管內存似乎確實地回答了這個問題。 – userx 2010-09-24 00:43:31

8

沒有,P /調用編組複製的非託管結構成員的值到結構的託管版本。通常,結構的託管版本與其非託管版本沒有任何兼容性。內存佈局不可發現,CLR使用重新訂購字段來使結構更小。編組是必不可少的,你創建一個副本。

修改結構對於給定的函數簽名是不可能的,因爲您可以填充傳遞給它的內存。該功能本身已經複製結構。但是,由於它是原始指針,因此您可以在Field2上進行派對。如果這指向一個結構,然後編組它自己Marshal.PtrToStructure()。修改它的託管副本並將其複製回到非託管內存中,其格式爲Marshal.StructureToPtr()。或者使用Marshal.ReadXxx()和WriteXxx()直接訪問它。

+0

這是我期望的,但我真的想在MSDN或類似的東西上尋找某種確認。 此外,Pack = 0也很好(它只是表示平臺默認值,對於使用相同代碼的x86和x64部署非常重要)。請參閱: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack.aspx – userx 2010-09-02 19:33:52

+1

這真的不是一個好地方找到鏈接,我推薦谷歌。 – 2010-09-02 19:41:18

+0

重申我在我的問題中所說的並不是真正的答案:)。我希望得到一些解釋微軟實施行爲的文檔。 – userx 2010-09-11 22:55:01

相關問題