2013-09-17 3 views
2

Я пытаюсь выстроить struct к byte[], а затем обратно, но я получаю ArgumentOutOfRangeException когда сортировочной обратно struct. Вот код:Struct SizeOf/Marshal.SizeOf изменение

public struct Response 
{ 
    CommandNumber Command; 
    ushort EstimatedRoundTripDuration; 
} 

protected TStruct ByteArrayToStruct<TStruct>(byte[] data) where TStruct : struct 
{ 
    TStruct resp = new TStruct(); 
    int size = Marshal.SizeOf(resp); 
    IntPtr ptr = Marshal.AllocHGlobal(size); 

    try 
    { 
     Marshal.Copy(data, 0, ptr, size); 
     Marshal.PtrToStructure(ptr, resp); 

     return resp; 
    } 
    finally 
    { 
     Marshal.FreeHGlobal(ptr); //cleanup just in case 
    } 
} 

Проблема, кажется, что sizeof(Response) является 3, в то время как Marshal.SizeOf(resp) равно 4. Я понимаю, что это может быть и, как ожидается, будет отличаться, но им с помощью достаточно базовых типов для этого struct. Может ли кто-нибудь пролить свет на то, почему размеры разные?

+2

Они могут быть и, как ожидается, будет отличаться. Ответил [здесь] (http://stackoverflow.com/questions/3361986/how-to-check-the-number-of-bytes-consumed-by-my-structure/3362736#3362736). –

ответ

2

Я предполагаю, что CommandNumber - один байт. Насколько я помню, слою взаимодействия нравится выравнивать поля данных. Таким образом, ваш EstimatedRoundTripDuration будет выровнен по следующему четному адресу, оставив один байт заполнения. Так это будет выглядеть следующим образом:

Command: 1 byte 
padding: 1 byte 
EstimatedRoundTripDuration: 1 byte 

Вы можете изменить поведение маршалинга с атрибутом StructLayout:

[StructLayout(LayoutKind.Sequential, Pack=1)] 
public struct Response 
{ 
    CommandNumber Command; 
    ushort EstimatedRoundTripDuration; 
} 
+0

Я забыл изменить перечисление на байт, но да, это 8 бит. Я предполагаю, что это «даже байтовое» заполнение основано на размере слова моей системы (64 бит) - это правильно? Только атрибут StructLayout не помог. Мне нужно изменить свойство Pack на 1. – Gusdor

+1

@Gusdor: Спасибо, что указали «Пакет». Я обновил свой ответ. –

+0

@Gusdor: заполнение «четным байтом» также будет выполняться на 32-битной машине. Я не знаю всех правил упаковки по умолчанию. Вам придется искать документацию для Pack, и, возможно, сделать немного больше исследований, чем это. –

Смежные вопросы