2014-06-10 2 views
0

Мне нужно создать экземпляр произвольного типа значений из байтов, хранящихся в каком-либо заданном смещении в массиве байтов (например, если тип int, должно быть принято 4 байта) , Я знаю, что могу легко сделать это с помощью указателей на фиксированные объекты, но я не хочу иметь код unsafe. Поэтому я стараюсь следующий код (проверки здравомыслия были зачищенные):Чтение значения произвольного типа из массива байтов

public object GetValueByType(System.Type type, byte[] byteArray, int offset) 
{ 
    int size = System.Runtime.InteropServices.Marshal.SizeOf(type); 
    MemoryStream memoryStream = new MemoryStream(); 
    memoryStream.Write(byteArray, offset, size); 
    memoryStream.Seek(0, System.IO.SeekOrigin.Begin); 
    BinaryFormatter binaryFormatter = new BinaryFormatter(); 
    object obj = (object)binaryFormatter.Deserialize(memoryStream); 
    return obj; 
} 

Но этот код перерывы в binaryFormatter.Deserialize.

Как я могу исправить вышеуказанный код (или достичь той же цели любым другим способом)?

+2

* Но этот код разбит на «binaryFormatter.Deserialize» * Как он прерывается? Исключение? Ошибка компиляции? Неверный выход программы? –

+1

'BinaryFormatter' ** не ** просто« читает произвольный тип значения из памяти ». Он работал бы только в том случае, если исходные данные * были сохранены * через 'BinaryFormatter'. Итак: как были сохранены исходные данные? –

+2

Кстати, это похоже на то, что вы на самом деле хотите, на полпути между «BitConverter» и «BinaryReader» –

ответ

1

В конце концов, нашел решение here (см ответить 50), и что окончательный код для Вашего удобства:

public object GetValueByType(Type typeOfReturnedValue, int offsetInDataSection) 
    { 
     GCHandle handle = GCHandle.Alloc(this.byteArray, GCHandleType.Pinned); 
     int offset = <some desired offset>; 
     IntPtr addressInPinnedObject = (handle.AddrOfPinnedObject() + offset); 
     object returnedObject = Marshal.PtrToStructure(addressInPinnedObject, typeOfReturnedValue); 
     handle.Free(); 
     return returnedObject; 
    } 

Таким образом, мой код остается без какого-либо опасного кода. Разве это не здорово ?!