Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Получить размер структуры, представить байтами


Автор: Lexicss 10.6.2009, 12:39
привожу фрагмент кода:
Код

        struct RecLogon2
        {
            public byte b1;
            public ushort len;
            public byte b2;
            public byte b3;
        }

Структура имеет 3 байтовых элеменат и 1 двухбайтовый. Итого её размер должен составлять 5 байт.

С помощью sizeOf() получаю неуправляемый размер 6. Почему?
Код

               RecLogon2 rc2;
               rc2 = new RecLogon2();
               rc2.b1 = 1;
               rc2.len = 13;
               rc2.b2 = 2;
               rc2.b3 = 3;

               int sz = Marshal.SizeOf(rc2);  // sz = 6, а не 5.    ???


когда выстраиваю структуру rc2 в виде массива байт то получаю результат
[1,0,13,0,2,3]

Откуда в этом массиве берётся первый ноль? И почему его длина составляет 6, а не 5? 

P.S. : если из структуры убрать элемент len, то её размер становится верный - 3 байта.


В чём тут суть такого фокуса и как его обойти?

Автор: DVariuS 10.6.2009, 13:01
Lexicss, это из-за выравнивания данных в памяти, смотри:
Код

            rc2.b1 = 1;
0000004c  mov         byte ptr [ebp-44h],1 
            rc2.len = 13;
00000050  mov         word ptr [ebp-42h],0Dh 
            rc2.b2 = 2;
00000056  mov         byte ptr [ebp-40h],2 
            rc2.b3 = 3;
0000005a  mov         byte ptr [ebp-3Fh],3 


а это строка в памяти, содержащая твою структуру:
Код

0x045FECBC  01 00 0d 00 02 03


Байты могут располагаться в памяти один за другим, а вот для размещения слова (word) компилятор берет следующий четный адресс. Это связано с оптимизацией для увеличения быстродействия, подробней можешь прочитать в любой книге по ассемблеру.

Цитата(Lexicss @  10.6.2009,  12:39 Найти цитируемый пост)
В чём тут суть такого фокуса и как его обойти?

При программировании на C# такие низкоуровневые моменты лучше не затрагивать, т.к. язык предназначен для других целей.

Автор: PashaPash 10.6.2009, 14:47
Lexicss, почитай про StructLayoutAttribute

Автор: Partizan 10.6.2009, 15:10
PashaPash, StructLayout разве влияет на размер структуры в managed-памяти?

я тут поигрался - результат всё тот же - sizeof выдаёт 6 байт...однако при копировании в unmanaged-блок памяти объект вполне себе и в 5 байт умещается...

Автор: PashaPash 10.6.2009, 16:06
Partizan, Marshal.SizeOf возвращает unmanaged size of an object in bytes. Покажи пример играния  smile

Автор: Partizan 10.6.2009, 16:37
PashaPash, 

Код

    [StructLayout(LayoutKind.Explicit)]
    struct RecLogon2
    {
        [FieldOffset(0)]
        public ushort len;
        [FieldOffset(2)]
        public byte b1;
        [FieldOffset(3)]
        public byte b2;
        [FieldOffset(4)]
        public byte b3;
        
    }

    class Program
    {
        static void Main(string[] args)
        {
            RecLogon2 rc2;
            rc2 = new RecLogon2();
            rc2.b1 = 1;
            rc2.len = 256;
            rc2.b2 = 2;
            rc2.b3 = 3;
            int sz = Marshal.SizeOf(rc2);  // sz = 6, а не 5.    ???
            
            IntPtr memBlock = Marshal.AllocHGlobal(5);
            Marshal.StructureToPtr(rc2, memBlock, false);
            
            RecLogon2 rc = (RecLogon2)Marshal.PtrToStructure(memBlock, typeof(RecLogon2));
            
            sz = Marshal.SizeOf(rc);
            
            Console.Write(sz);//6
        }
    }


Добавлено через 3 минуты и 14 секунд
А, всё...понял почему...Не выставил параметр атрибута Size smile
если Size выставить значение 5, то всё ок.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)