我正在围绕C库编写一个Rust包装器。 C库提供以下功能:
void lib_foo(const unsigned char *buf, uint32_t buf_len);
我创建了以下
extern
包装器:fn lib_foo(buf: *const u8, buf_len: u32);
和以下高级包装器:
pub fn foo(buf: &[u8]) {
unsafe { lib_foo(buf.as_ptr(), buf.len() as u32) }
}
但是,从
usize
(buf.len()
的类型)到u32
的转换可能会导致大小被截断。处理此问题的最佳方法是什么? 最佳答案
首先,请使用 libc
crate 输入类型。
即:extern fn lib_foo(buf: *const libc::c_uchar, buf_len: libc::uint32_t);
虽然稍长一些,但可以避免做出假设(unsigned char
映射到u8
)并使翻译自动进行。
然后,进入高级包装器。
在没有任何假设的情况下,最简单的解决方案是 panic 并记录下来。
/// Calls `lib_foo`, ...
///
/// # Panics
///
/// If the size of the buffer is strictly greater than 2^32-1 bytes.
pub fn foo(buf: &[u8]) {
assert!(buf.len() <= (std::u32::MAX as usize));
unsafe { lib_foo(buf.as_ptr() as *const _, buf.len() as libc::uint32_t) }
}
然后,根据域,可能会出现其他选择:
std::cmp::min
)在任何情况下,如果用户可以观察到行为差异,请记录文档。
关于c - 如何处理将usize传递给期望uint32_t的C函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40255192/