2015-09-26 98 views
4

我寫了一段代碼片段來演示這個問題。 的問題是,當我聲明一個結構用Layout.Explicit狀態, 它分配一個未定義的值,這取決於其它值結構的字段。 只有在使用Layout.Explicit狀態時纔會出現此問題。 這是很難解釋沒有代碼,所以這裏是一個簡短的例子。奇怪的結構行爲

using System.Runtime.InteropServices; 
namespace ConsoleStruct 
{ 
    class Program 
    { 
     [StructLayout(LayoutKind.Explicit)] 
     struct TestStruct 
     { 
      [FieldOffset(0)] 
      public double dbl; 
      [FieldOffset(0)] 
      public ulong uu; 
     } 

     public static void SimpleMethod() 
     { 
      TestStruct st; 
      st.uu = 0; 
      st.dbl = 5000.0; 
      Console.WriteLine(st.uu.ToString()); // ==> uu becomes 4662219572839972864 
               //instead of 0 :(
               // it looks like the value of uu is dependent on the 
               //value assigned to dbl 
      Console.ReadLine(); 
     } 
     static void Main(string[] args) 
     { 
      SimpleMethod(); 
     } 
    } 
} 

任何人都可以向我解釋爲什麼會發生這種情況。使用VS 2013. 謝謝。

+5

嗯,是的,這正是定義具有相同FieldOffset領域的角度來看,它們重疊,因爲你*明確要求它* – harold

+0

嗯,不知道的誤會是在這裏。你認爲'[FieldOffset(0)]'有什麼作用?你想要完成什麼? – usr

回答

8

它看起來像UU的值取決於分配給DBL

是的,它是值。因爲你給了它們相同的偏移量,它們佔用了內存中相同的位置(在結構體內)。

[FieldOffset(...)]可以手動佈局的領域,你可以讓他們重疊。一些非託管API需要這樣做。

注意,當你嘗試一些重疊與參考字段(如字符串),你會得到一個運行時異常。內存安全只有在您僅使用值類型進行操作時才能維持。

+0

所以只是爲了說清楚,要解決這個問題,他是否必須將'uu'的屬性FieldOffset更改爲'1'?或'sizeof(double)'?或者FieldOffset –

+0

的一般想法是什麼,你將不得不將它提升爲'sizeof(double)'。可能有其他平臺限制(對齊)。總體思路是準確地映射出結構,通常是爲了匹配外部規範。 –

+0

好的,所以你放心我的想法,即FieldOffset需要字節來抵消。謝謝 –