【发布时间】:2020-05-15 09:09:49
【问题描述】:
我想转移以下C代码
HMAC_CTX context;
HMAC_CTX_init(&context);
进入 Rust。但是,虽然定义 extern 函数很容易,但在 Rust 中直接使用 C 结构似乎是不可能的。
extern "C" {
use HMAC_CTX; // does not work!
fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
}
我知道我可以在 Rust 中定义一个占位符结构
struct HMAC_CTX;
...但是 的实例可能没有足够的空间容纳真正的 C 结构体。
let mut ctx = HMAC_CTX;
unsafe { HMAC_CTX_init(&mut ctx); }
有没有办法在不重新定义整个 Rust 结构的情况下解决这个问题?这将创建从外部代码到我的 Rust 项目的依赖关系,我想避免这种情况。
【问题讨论】:
-
大多数人使用
rust-bindgen。这能解决你的问题吗? -
" 但是,虽然定义 extern 函数很容易,但在 Rust 中直接使用 C 结构似乎是不可能的。"当然。 extern 声明提供了要调用的函数的签名,但从根本上讲,它们并不相关。对于结构,签名是整个结构定义。
-
“它可能会解决问题,但我想避免使用代码生成器。”那么您可以手动对其进行代码生成:复制/粘贴原件,将其标记为
repr(C)并修复类型和所有方面的差异。 -
更好的方法一是使用现有的绑定(openssl-sys 或更高级别的 openssl crate),更好的方法二是使用 bindgen。我不知道更好的方法 3.
-
HMAC_CTX是一个不透明的结构。它的布局和内容永远不会出现在客户端代码中。它只用作HMAC_CTX*,即指针。因此,您的客户端 (Rust) 代码不需要了解其内部结构。对于客户端代码,这只是一个指向 OpenSSL 控制的一些数据的指针。