pub trait OpaqueStruct: Sized {
    type CType: Sized;

    fn null_value() -> Self { ... }
    unsafe fn with_ref<T, F: Fn(&Self) -> T>(cptr: *const Self::CType, f: F) -> T { ... }
    unsafe fn with_ref_mut<T, F: Fn(&mut Self) -> T>(
        cptr: *mut Self::CType,
        f: F
    ) -> T { ... } unsafe fn initialize(cptr: *mut Self::CType, rval: Self) { ... } unsafe fn return_val(self) -> Self::CType { ... } unsafe fn take(cptr: *mut Self::CType) -> Self { ... } }
Expand description

This trait supports structs allocated by C but managed by Rust.

This is useful for commonly-used data types that have a fixed size, to avoid allocating the data type itself on the heap.

This approach uses a “regular” Rust type in the Rust code, and a C type with a _reserved field to reserve the space on the C stack. The tricky bit is to convince the C code to allocate enough space to store the Rust value. There is no constant way to determine the space required for a Rust value, but it is possible to make a conservative guess, possibly leaving some unused space. The suggested C type is struct CType([u64; N]) for some N large enough to contain the Rust type on the required platforms. In C, this type would be defined as struct ctype_t { _reserved uint64_t[N] } for the same N. The types must also have the same alignment.

This type contains debug assertions regarding the size of the Rust and C types, and will fail at runtime if the alignment or size of the two types is not as required.

This type provides two functions useful for initialization of a type: initialize takes an “out arg” pointing to an uninitialized value, and initializes it; while return_val simply returns a struct value that can be used to initialize a variable. Both function similarly, so choose the one that makes the most senes for your API. For example, a constructor which can also return an error may prefer to put the error in the return value and use initialize.

Safety

C allows uninitialized values, while Rust does not. Be careful in the documentation for the C API to ensure that values are properly initialized before they are used.

Required Associated Types§

The C representation of this type. This must have the same alignment as Self and its size must not be less than that of Self.

Provided Methods§

Get the value of this type used to represent a NULL pointer.

For types that have a natural zero value, this can provide a shortcut for a C caller: instead of initializing a struct with the zero value and apssing a pointer to it, the caller can simply pass NULL.

The default implementation panics.

Call the contained function with a shared reference to the data type.

Safety
  • for types defining [null_value]: cptr must be NULL or point to a valid CType value
  • for types not defining [null_value]: cptr must not be NULL and must point to a valid CType value
  • no other thread may mutate the value pointed to by CType until with_ref returns.

Call the contained function with an exclusive reference to the data type.

Safety
  • for types defining [null_value]: cptr must be NULL or point to a valid CType value
  • for types not defining [null_value]: cptr must not be NULL and must point to a valid CType value
  • no other thread may access the value pointed to by CType until with_ref_mut returns.

Initialize the value pointed to cptr with rval, “moving” rval into the pointer.

Safety
  • cptr must not be NULL, must be aligned for CType, and must have enough space for CType.
  • to avoid a leak, the value must eventually be moved out of *cptr and into a Rust value to be dropped (see OpaqueStruct::take)

Return a CType containing self, moving self in the process.

Safety
  • to avoid a leak, the value must eventually be moved out of the return value and into a Rust value to be dropped (see OpaqueStruct::take)

Take a CType and return an owned value.

This method is used for “xxx_free” functions, which simply drop the resulting owned value.

It is also used for functions which are documented in the C API as consuming the given value, saving the caller the trouble of separately freeing the value.

The memory pointed to by cptr is zeroed to prevent accidental re-use.

Safety
  • for types defining [null_value]: cptr must be NULL or point to a valid CType value
  • for types not defining [null_value]: cptr must not be NULL and must point to a valid CType value
  • the memory pointed to by cptr is uninitialized when this function returns

Implementors§