- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力通过接受 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 并返回。
最佳答案
您不能将struct 转换为c_void
,但可以将reference 转换为*mut c_void
并返回使用一些指针转换:
fn my_callback(con: *tsm_screen, ..., data: *mut c_void) {
// unsafe is needed because we dereference a raw pointer here
let data: &mut State = unsafe { &mut *(data as *mut State) };
println!("state: {}", data.state);
state.x = 10;
}
// ...
let mut state = State { state: 20 };
let state_ptr: *mut c_void = &mut state as *mut _ as *mut c_void;
tsm_screen_draw(con, my_callback, state_ptr);
也可以使用 std::mem::transmute()
函数在指针之间进行转换,但它比这里真正需要的工具强大得多,应尽可能避免使用。
请注意,您必须格外小心地将不安全指针强制转换回引用。如果 tsm_screen_draw
在另一个线程中调用它的回调或将其存储在全局变量中,然后另一个函数调用它,那么当回调执行时,state
局部变量很可能超出范围调用,这将使您的程序崩溃。
关于ffi - 在 FFI 中使用 c_void,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24191249/
UnsafeCell documentation说 The UnsafeCell type is the only legal way to obtain aliasable data that is
这个问题在这里已经有了答案: Why would it be necessary to perform two casts to a mutable raw pointer in a row? (1
我正在为库编写绑定(bind),其中在Rust中有一个参数类型为void* aka *mut c_void的函数。我必须为此参数分配一个数组,如何在Rust中做到这一点? 我试过强制转换transmu
我需要在 Rust 线程之间共享从 C++ 创建的对象。我已经将它包装在一个 Mutex 结构中,所以现在在线程之间发送是安全的。但是编译器不会让我做什么。 error[E0277]: `*mut
我正在尝试调用 setsockopt但无法弄清楚 c_void 的转换。 IP_HDRINCL 不在 nix 或 socket 包中,所以我必须使用 libc。我以 How to set the so
我正在努力通过接受 void 的 FFI 传递结构并在另一端读回它。 有问题的库是 libtsm,一个终端状态机。它允许您提供输入,然后找出输入后终端将处于哪种状态。 它将其绘制函数声明为: pub
这个问题在这里已经有了答案: How can I call a raw address from Rust? (1 个回答) 关闭 3 年前。 互联网的 friend 们好, 我正在努力调用存储在
我有一个 C++ 数组形式的矩阵,想将其传递给用 Rust 编写的共享库函数。我有这样的东西 #![crate_type = "dylib"] extern crate libc; use libc:
我一直在尝试用 Rust 编写 Redis 模块。这是我第一次尝试使用 Rust FFI 和绑定(bind)。如何在不破坏 Redis 指针的情况下调用此方法并在 Rust 中得到一个数据值? ext
这是我使用 c2rust 生成的一些代码然后清理了一下: #![feature(libc)] extern crate libc; use libc::*; use std::mem::transmu
我是一名优秀的程序员,十分优秀!