Как я могу memcpy между * c_char и Vec - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть Vec<u8>, который притворяется большим диском:

lazy_static! {
    static ref DISK: Mutex<Vec<u8>> = Mutex::new(vec![0; 100 * 1024 * 1024]);
}

Мой код Rust (вызывается непосредственно из C) имеет некоторые функции для чтения и записи на этот диск, но я нене понимаю, что я написал бы в этих функциях для memcpy между диском и вызывающей стороной C (или если Vec - лучшая структура для использования здесь вообще):

extern "C" fn pread(
    _h: *mut c_void,
    buf: *mut c_char,
    _count: uint32_t,
    offset: uint64_t,
    _flags: uint32_t,
) -> c_int {
    // ?
}

extern "C" fn pwrite(
    _h: *mut c_void,
    buf: *const c_char,
    _count: uint32_t,
    offset: uint64_t,
    _flags: uint32_t,
) -> c_int {
    // ?
}

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Использование std::ptr::copy_nonoverlapping.

use std::ptr;

// Copy from disk to buffer
extern "C" unsafe fn pread(
    _h: *mut c_void,
    buf: *mut c_char,
    count: uint32_t,
    offset: uint64_t,
    _flags: uint32_t,
) -> c_int {
    // TODO: bounds check
    ptr::copy_nonoverlapping(&DISK.lock()[offset], buf as *mut u8, count);
    count
}
0 голосов
/ 08 февраля 2019

используйте Cstring::from_raw(buf).into_bytes() и наоборот ( документация ) для преобразования buf в / из байтового фрагмента, затем copy_from_slice для копирования данных в DISK - эта функция использует memcpyвнутри

...