Trait ffizz_passby::OpaqueStruct
source · 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§
Provided Methods§
sourcefn null_value() -> Self
fn null_value() -> Self
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.
sourceunsafe fn with_ref<T, F: Fn(&Self) -> T>(cptr: *const Self::CType, f: F) -> T
unsafe fn with_ref<T, F: Fn(&Self) -> T>(cptr: *const Self::CType, f: F) -> T
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.
sourceunsafe fn with_ref_mut<T, F: Fn(&mut Self) -> T>(
cptr: *mut Self::CType,
f: F
) -> T
unsafe fn with_ref_mut<T, F: Fn(&mut Self) -> T>(
cptr: *mut Self::CType,
f: F
) -> T
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.
sourceunsafe fn initialize(cptr: *mut Self::CType, rval: Self)
unsafe fn initialize(cptr: *mut Self::CType, rval: Self)
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)
sourceunsafe fn return_val(self) -> Self::CType
unsafe fn return_val(self) -> Self::CType
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)
sourceunsafe fn take(cptr: *mut Self::CType) -> Self
unsafe fn take(cptr: *mut Self::CType) -> Self
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