rustffiopaque-types

Cross-compile-safe way of defining a Rust type representing an opaque C struct whose size is known at compile-time


I need to define a Rust type that reflects an opaque C struct whose size and alignment requirements are known at compile-time. A helpful individual suggested I generate code like

#[repr(C, align($ALIGNMENT_GOES_HERE))]
pub struct Foo(std::mem::MaybeUninit<[u8; $SIZE_GOES_HERE]>);

from a C program, with $SIZE_GOES_HERE and friends filled in according to what I determine from there. This works great, but is not at all robust in cases of cross-compilation if the size and alignment are platform-dependent.

Are there any robust solutions for this? The cc crate looks promising.


Solution

  • The size and alignment of a given struct for a particular target architecture are determined by the struct's layout and the target architecture's ABI.

    If Rust does not have the struct's layout, then it cannot determine its size or alignment—so it must be explicitly furnished with this information.

    However, because this information is target-dependent, providing it in advance of compilation will limit the possible targets to those that have been hard-coded (e.g. via different definitions, selected by conditional compilation).

    Instead, there is an official tool called bindgen that can automatically generate the appropriate Rust binding from the C header file as a build step at compilation-time. It can be configured to treat a type as an opaque blob of bytes, if so desired.