我正在努力通过一个接受void参数的FFI传递结构体,并在另一端读取它。
所涉及的库是libtsm,一个终端状态机。它允许您提供输入,然后找出输入后终端处于哪个状态。
它声明了其绘制函数为:
pub fn tsm_screen_draw(con: *tsm_screen, draw_cb: tsm_screen_draw_cb, data: *mut c_void) -> tsm_age_t;
tsm_screen_draw_cb是由库的用户实现的回调函数,签名如下:
pub type tsm_screen_draw_cb = extern "C" fn(
con: *tsm_screen,
id: u32,
ch: *const uint32_t,
len: size_t,
width: uint,
posx: uint,
posy: uint,
attr: *tsm_screen_attr,
age: tsm_age_t,
data: *mut c_void
);
这里重要的部分是data
参数,它允许用户传递指向自己实现的状态的指针,在绘制后操纵和使用它。给定一个简单结构体:
struct State {
state: int
}
我应该如何正确地做到这一点?我不确定如何将指向结构体的指针正确地转换为void类型,然后再转回来。
transmute
函数:它非常强大,而且很容易出现错误地转换某些东西的情况。你可以直接使用as
处理指针,例如let data = &mut *(data as *mut State);
和let state_ptr = &mut state as *mut _ as *mut c_void;
。(特别是编写&mut *...
,因为那样可以保证你正在处理指针,而不像transmute
那样不确定。) - huonstate
已经超出了作用域并被销毁。请仔细检查您的回调函数是否仅在state
仍然存在时才被调用。 - Vladimir Matveev