Я играл с написанием модулей Redis в Rust. Это моя первая попытка использования Rust FFI и привязок. Как мне вызвать этот метод и получить значение данных в Rust, не уничтожая указатель Redis?
extern "C" {
pub static mut RedisModule_GetTimerInfo: ::std::option::Option<
unsafe extern "C" fn(
ctx: *mut RedisModuleCtx,
id: RedisModuleTimerID,
remaining: *mut u64,
data: *mut *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_int,
>;
}
См. Документацию API RedisModule_GetTimerInfo для получения более подробной информации.
Я закончил тем, что заставил это работать, но он выдает ошибку, если я вызываю это с тем же id
дважды:
let mut ms = 0 as u64;
let val = "";
let ptr = Box::into_raw(Box::new(&mut val)) as *mut *mut c_void;
let ok = unsafe { RedisModule_GetTimerInfo.unwrap()(ctx, id, &mut ms, ptr) };
let mut data: Option<String> = None;
if ok == 0 {
let val = unsafe { Box::from_raw(*ptr as *mut &str) };
// trim nul bytes
data = Some(val.trim_matches(char::from(0)).to_string());
}
Это не сработало из-за того, что Box::from_raw
владеет необработанным указателем и указатель уничтожается при удалении окна.
Я пробовал бесчисленное множество способов сделать эту работу без использования Box::into_raw
& Box::from_raw
, и все время они либо заканчивали тем, что сбивали Redis, либо оказывались указателем что я не знаю, как конвертировать в &str
.
Обновление: у меня изначально был пример использования RedisModule_StopTimer
, что было ошибкой. Исправлено использование метода, о котором я спрашивал.