2016-07-15 9 views
2

Если у меня есть struct, например:Копирование-структуру в определенном месте памяти в Русте

#[derive(Clone, Copy)] 
#[repr(C, packed)] 
pub struct SomeData { 
    a: u16, 
    b: u64, 
    c: u32, 
    d: u16, 
} 

Как скопировать его в определенное место в памяти, например, до точки 0x1000 в памяти эффективно? Будет что-то вроде этой работы?

let dst_addr: u64 = 0x1000; 
let src = SomeData {a: 1, b: 2, c: 3, d: 4}; 
unsafe { 
    let tmp: &[u8; 10] = transmute(src); 
    copy(dst_addr as *mut _, tmp); 
} 

Пожалуйста, обратите внимание, что repr(C, packed) часть на самом деле нужны.

Программное обеспечение работает на голой x86_64, кольце 0, без операционной системы или других ограничений. Кроме того, я программирую без стандартной библиотеки, поэтому это должно быть возможно только с библиотекой core.

Это, конечно, небезопасно, но это не проблема.

Редактировать: Просто уточнение: я копирую в неинициализированную память.

+1

Есть несколько полезных уроков о написании собственного ядра, включая [* Написание ОС в Rust в крошечных шагах * Джулия Эванс] (http://jvns.ca/blog/2014/03/12/the- rust-os-story /) и [* Написание ОС в Rust * от Филиппа Оппермана] (http://os.phil-opp.com/) и по крайней мере два больших проекта: [Intermezzos] (https: // intermezzos .github.io/book /) и [Redox] (https://github.com/redox-os/redox). – Shepmaster

+0

@Shepmaster Да, я прочитал оба. Я просто задавался вопросом, что такое «правильный» способ сделать это, поскольку учебники не всегда правильны, и если были какие-то отличные «трюки», о которых я не знал. –

+0

Я думаю, что эти учебные пособия полностью читаются сообществом, когда они отправляются на субреддит или форум пользователя, или даже в Hacker News. Я бы ожидал, что они будут хорошо рассмотрены. – Shepmaster

ответ

6

Вы хотите ознакомиться с модулем core::ptr.

write Его функция делает именно то, что вы хотите:

pub unsafe fn write<T>(dst: *mut T, src: T) 
core::ptr::write(dst_addr as *mut_, src); 

Как уже отмечалось, он не падает от текущего значения dst_addr (вы можете использовать read сделать это).

Я не рекомендую использовать intrinsics::copy_nonoverlapping, так как встроенные функции никогда не будут стабилизированы.

+0

Это сработало => принято! Должен использовать 'ptr :: write (dst_addr as * mut SomeData, * self);' потому что я делал это внутри метода 'SomeData'. –