【发布时间】:2016-12-14 12:35:33
【问题描述】:
当我开始学习 Rust 时,我天真地假设 Rust 指向特征的指针就像 C++ 指向基类的指针一样实现,并编写了一些即使在这种假设下也能工作的代码。具体来说,我编写的代码与需要读取和查找流的 FFI 库接口,它是这样的:
struct StreamParts {
reader: *mut Read,
seeker: *mut Seek,
}
fn new_ffi_object<T: Read + Seek + 'static>(stream: T) -> FFIObject {
let stream_ptr = Box::into_raw(Box::new(stream));
let stream_parts = Box::into_raw(Box::new(StreamParts {
reader: stream_ptr as *mut Read,
seeker: stream_ptr as *mut Seek,
}));
ffi_library::new_object(stream_parts, ffi_read, ffi_seek, ffi_close)
}
extern "C" fn ffi_read(stream_parts: *mut StreamParts, ...) -> c_ulong {
(*stream_parts.reader).read(...)
...
}
extern "C" fn ffi_seek(stream_parts: *mut StreamParts, ...) -> c_ulong {
(*stream_parts.seeker).seek(...)
...
}
extern "C" fn ffi_close(stream_parts: *mut StreamParts) {
mem::drop(Box::from_raw(stream_parts.reader));
mem::drop(Box::from_raw(stream_parts));
}
它奏效了。但是,我不完全理解它为什么起作用的三件事:
- Rust 的特征对象很胖,包含两个指针。因此,与 C++ 不同,
*mut Read是指向特征对象的指针,对吗?这个特征对象在哪里分配? Rust 文档没有涉及这个具体案例。 - 我是否正确假设
mem::drop(Box::from_raw(stream_parts.reader))完全丢弃原始流? - 为什么
new_ffi_object()中需要'static?
【问题讨论】:
-
有趣的问题;我知道 Rust 引用很胖,但我不知道指针是否是(我认为它们必须是?)。
-
One question per question, please。想想你是什么时候搜索这些问题的答案的(你确实搜索过,对吧?)。 你会点击标题为“pointer to trait”的问题来获取这些要点中的任何一个吗? SO 不是要回答您的 问题,而是要为每个人 建立一个世界级的知识库以供将来参考。我保证如果您单独提出问题,至少其中一个问题已经得到回答。