I would like to transfer the following C code
HMAC_CTX context;
HMAC_CTX_init(&context);
into Rust. But while it's easy to define an extern function, it seems impossible to directly use a C struct in Rust.
extern "C" {
use HMAC_CTX; // does not work!
fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
}
I know that I could define a placeholder struct in Rust
struct HMAC_CTX;
...but an instance of may not hold enough space for the real C struct.
let mut ctx = HMAC_CTX;
unsafe { HMAC_CTX_init(&mut ctx); }
Is there a way of solving this without redefining the whole struct in Rust? That would create a dependency from the external code to my Rust project and I would like to avoid this.
Use rust-bindgen
to generate Rust bindings. It'll generate a rust version of the corresponding C struct and keep it synchronized if placed in the build-script.
Adds complexity to the build process and adds a dependency.
Create a Rust version of the C struct by hand.
#[repr(C)]
pub struct HMAC_CTX {
md: *mut EVP_MD,
md_ctx: EVP_MD_CTX,
i_ctx: EVP_MD_CTX,
o_ctx: EVP_MD_CTX,
key_length: c_uint,
key: [c_uchar; 128],
}
This requires to follow changes of the C code and manually update the Rust struct. Also further structs might have to be defined. Add a dependency to the internals of the called library:-(
Create a placeholder struct.
pub struct HMAC_CTX {
_placeholder: [c_uchar; 256],
}
This struct needs to be large enough to hold all the internals of the C struct. Indirect dependency:-( If the C struct size exceeds the placeholder size, it could lead to unsafe behavior.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.