我正在努力将结构传递给FFI,FFI接受void并在另一端读回来.
有问题的库是libtsm,一个终端状态机.它允许您输入输入,然后找出输入后终端的状态.
它将draw函数声明为:
pub fn tsm_screen_draw(con: *tsm_screen, draw_cb: tsm_screen_draw_cb, data: *mut c_void) -> tsm_age_t;
Run Code Online (Sandbox Code Playgroud)
其中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
);
Run Code Online (Sandbox Code Playgroud)
这里重要的部分是data参数.它允许用户通过指向自我实现状态的指针,对其进行操作并在绘制后使用它.给出一个简单的结构:
struct State {
state: int
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?我不确定如何正确地将指向结构的指针转换为void和back.
在查看时unix-socket,我遇到了这段代码:
let timeout = unsafe {
let mut timeout: libc::timeval = mem::zeroed();
let mut size = mem::size_of::<libc::timeval>() as libc::socklen_t;
try!(cvt(libc::getsockopt(self.0,
libc::SOL_SOCKET,
kind,
&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _)));
timeout
};
Run Code Online (Sandbox Code Playgroud)
我特别好奇这些线条:
&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _
Run Code Online (Sandbox Code Playgroud)
为什么有必要对一行中的可变原始指针执行两次转换?为什么仅仅施放一次就不够了?