小编Ska*_*ade的帖子

在FFI中使用c_void

我正在努力将结构传递给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.

ffi rust

16
推荐指数
1
解决办法
1万
查看次数

解决扩展特征的局限性

具有对象安全特性FooFooExt为所有实例实现的(可能不安全的)扩展特征的模式Foo现在似乎成为标准.

https://github.com/rust-lang/rfcs/pull/445

对于我来说这是一个问题Iterator<A>,因为我有一个库来覆盖IteratorExt#last()旧迭代器特征的默认方法(底层库有一个有效的实现last()).现在这是不可能的,因为对于任何人来说A,总会有一个冲突的特质实施IteratorExt,即libcore已经为所有人提供的实施Iterator<A>.

iterator.rs:301:1: 306:2 error: conflicting implementations for trait `core::iter::IteratorExt` [E0119]

iterator.rs:301 impl<'a, K: Key> iter::IteratorExt<Vec<u8>> for ValueIterator<'a,K,Vec<u8>> {
iterator.rs:302   fn last(&mut self) -> Option<Vec<u8>> {
iterator.rs:303      self.seek_last();
iterator.rs:304      Some(self.value())
iterator.rs:305   }
iterator.rs:306 }
...
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,我有两个选择:

  • 有我自己的特点和我自己的last()实现.IteratorExt除非仔细使用,否则这意味着它会导致冲突.last()如果使用版本from,这也有意外使用低效版本的危险IteratorExt.我放松了方便的访问IteratorExt.
  • 拥有自己的特征并以不同方式命名方法(seek_last()).缺点:我要求用户学习词汇,并总是喜欢我的方法而不是提供的方法IteratorExt.同样的问题:我想避免意外使用last().

我还缺少其他更好的解决方案吗?

iterator traits rust

8
推荐指数
1
解决办法
400
查看次数

标签 统计

rust ×2

ffi ×1

iterator ×1

traits ×1