c - 如何处理将 usize 传递给需要 uint32_t 的 C 函数?

标签 c rust ffi

我正在围绕 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/

相关文章:

c - 有效地将随机字节转换为字符串而不会损失太多熵

c++ - Xlib:XGetWindowAttributes 总是返回 1x1?

testing - 如何设置 RUST_TEST_TASKS 环境变量?

rust - 打开 API 生成器。 rust 和 rust-server 客户端有什么区别?

rust - 如何在不移出参数的情况下实现 std::ops:{Add, Sub, Mul, Div} 运算符之一?

windows - 转到异常 "signal arrived during cgo execution"

c - 从 Rust FFI 访问 DPDK 中的静态 C 函数

c# - Visual Studio 查看 DLL 中的 StandardOuptut 流

c - 堆地址范围内全局变量的地址

haskell - 无法在 Haskell 中链接 FFI 库