2015-09-26 5 views
4

Я написал небольшой фрагмент кода, чтобы продемонстрировать эту проблему. Проблема заключается в том, что когда я объявляю структуру с состоянием Layout.Explicit, присваивает неопределенное значение полям этой структуры в зависимости от другого значения. Эта проблема возникает только при использовании состояния Layout.Explicit. довольно сложно объяснить без кода, поэтому вот краткий образец.Weird Struct Behavior

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

это выглядит как значение УУ зависит от значения, присвоенного ДВМ

Да это. Поскольку вы дали им одинаковые смещения, они занимают одно и то же место в памяти (внутри структуры).

[FieldOffset(...)] позволяет вам компоновать поля вручную, и вы можете сделать их перекрывающимися. Некоторые неуправляемые API требуют этого.

Обратите внимание, что при попытке совместить что-либо с ссылочным полем (например, с строкой) вы получите исключение во время выполнения. Безопасность памяти может поддерживаться только до тех пор, пока вы делаете это только с типами значений.

+0

Чтобы просто понять, исправить это, должен ли он изменить атрибут FieldOffset 'uu' на' 1'? или 'sizeof (double)'? или какая общая идея FieldOffset –

+0

Вам нужно поднять его до 'sizeof (double)'. Могут быть другие ограничения платформы (выравнивание). Основная идея состоит в том, чтобы точно структурировать структуру, обычно соответствующую внешней спецификации. –

+0

Итак, вы заверили, что я думал, что FieldOffset берет байт, чтобы компенсировать. Спасибо –