2015-11-28 1 views

ответ

3

Как предполагает DK, вы, вероятно, не должны использовать код unsafe, чтобы переосмыслить память. Но вы можете, если хотите.

Если вы действительно хотите, чтобы идти по этому пути, вы должны знать несколько подводных камней:

  • Вы можете иметь проблемы с выравниванием. Если вы просто возьмете откуда-нибудь и захотите, чтобы он временно преобразовал его в &mut[u16], он мог бы ссылаться на некоторую область памяти, которая не соответствует , выровненному для доступа к u16. В зависимости от того, на каком компьютере вы запускаете этот код, такой неприглаженный доступ к памяти может быть незаконным. В этом случае программа, вероятно, будет прервана. Например, процессор может генерировать какой-то сигнал, на который реагирует операционная система, чтобы убить процесс.
  • Он не переносится. Даже без проблем с выравниванием вы получите разные результаты на разных машинах (маленькие или большие конечные машины).

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

/// warning: The resulting byte view is system-specific 
unsafe fn raw_byte_access(s16: &mut[u16]) -> &mut[u8] { 
    use std::slice; 
    slice::from_raw_parts_mut(s16.as_mut_ptr() as *mut u8, 
           s16.len() * 2) 
} 

Конечно, на большой endian machine эта функция не делает то, что вы хотите. Вам нужен небольшой порядковый байтовый порядок. Таким образом, вы можете использовать это только как оптимизацию для маленьких конечных машин и должны придерживаться решения, такого как DK для больших/смешанных конечных машин.

10

Очевидным, безопасным и переносным способом является просто использовать математику.

fn set_u16_le(a: &mut [u8], v: u16) { 
    a[0] = v as u8; 
    a[1] = (v >> 8) as u8; 
} 

Если вы хотите интерфейс более высокого уровня, есть byteorder ящик, который предназначен, чтобы сделать это.

Вы определенно должны не использование transmute превратить [u8] в [u16], потому что не гарантирует ничего о порядке байтов.

+0

Ну, да, это то, что у меня есть прямо сейчас, но мне было интересно узнать о микрооптимизации, и в любом случае вы не можете использовать '# [cfg (target_endian =" ... ")]' для проверки для байтового заказа? – Shien

+0

@Shien Обычно вы можете получить битрейт, чтобы быть почти оптимальным. Я бы не стал беспокоиться об этом в большинстве случаев использования. – Veedrac

+0

Я не вижу, как ваш ответ действительно заботится о порядке байтов. – Neikos

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