Boxed

Struct Boxed 

Source
#[non_exhaustive]
pub struct Boxed<RType: Sized> { /* private fields */ }
Expand description

Boxed is used to model values that are passed by reference and where their memory allocation is managed entirely by Rust. These are represented in the C API by a pointer, with “new” and “free” functions handling creation and destruction.

The value may be opaque to C, so that it may not access fields in the struct directly, in which case RType can be any Rust type. Otherwise, if a C structure is provided, you must use #[repr(C)] to ensure that C and Rust lay out the struct identically.

§Example

Define your C and Rust types, then a type alias parameterizing Boxed:

struct System {
    // ...
}
type BoxedSystem = Boxed<System>;

Then call static methods on that type alias.

Implementations§

Source§

impl<RType: Sized> Boxed<RType>

Source

pub unsafe fn take_nonnull(arg: *mut RType) -> RType

Take a value from C as an argument, taking ownership of the value it points to.

Be careful that the C API documents that the passed pointer cannot be used after this function is called.

If you would like to borrow the value, but leave ownership with the calling C code, use Boxed::with_ref or its variants.

This function is most common in “free” functions, but can also be used in contexts where it is ergonomic for the called function to consume the value. For example, a database connections’s execute method might reasonably consume a query argument.

db_query_t q = db_query_new();
db_query_set_filter(q, "x = 10");
db_query_add_column(q, "y");
db_result_t res = db_execute(db, q);

Here it’s natural to assume (but should also be documented) that the db_execute function takes ownership of the query.

§Safety
  • arg must not be NULL (see Boxed::take for a version allowing NULL).
  • arg must be a value returned from Box::into_raw (via Boxed::return_val or Boxed::to_out_param or a variant).
  • arg becomes invalid and must not be used after this call.
Examples found in repository?
examples/status.rs (line 167)
163pub unsafe extern "C" fn hittr_system_free(system: *mut System) {
164    // SAFETY:
165    //  - system is valid and not NULL (see docstring)
166    //  - caller will not use system after this call (see docstring)
167    unsafe { BoxedSystem::take_nonnull(system) };
168    // (System is implicitly dropped)
169}
Source

pub unsafe fn with_ref_nonnull<T, F: FnOnce(&RType) -> T>( arg: *const RType, f: F, ) -> T

Call the contained function with a shared reference to the value.

§Safety
  • arg must not be NULL (see Boxed::with_ref for a version allowing NULL).
  • No other thread may mutate the value pointed to by arg until this function returns.
  • Ownership of the value remains with the caller.
Examples found in repository?
examples/status.rs (lines 234-238)
228pub unsafe extern "C" fn hittr_system_status(system: *const System) -> hittr_status_t {
229    // SAFETY:
230    // - system is not NULL and valid (see docstring)
231    // - system is valid for the life of this function (documented as not threadsafe)
232    // - system will not be modified during the life of this function (documented as not threadsafe)
233    unsafe {
234        BoxedSystem::with_ref_nonnull(system, |system| {
235            // SAFETY:
236            // - hittr_status_t is not allocated, so no issues
237            unsafe { StatusValue::return_val(system.status) }
238        })
239    }
240}
Source

pub unsafe fn with_ref_mut_nonnull<T, F: FnOnce(&mut RType) -> T>( arg: *mut RType, f: F, ) -> T

Call the contained function with an exclusive reference to the value.

§Safety
  • arg must not be NULL (see Boxed::with_ref_mut for a version allowing null)
  • No other thread may access the value pointed to by arg until this function returns.
  • Ownership of the value remains with the caller.
Examples found in repository?
examples/status.rs (lines 189-191)
183pub unsafe extern "C" fn hittr_system_run(system: *mut System) {
184    // SAFETY:
185    // - system is not NULL and valid (see docstring)
186    // - system is valid for the life of this function (documented as not threadsafe)
187    // - system will not be accessed during the life of this function (documented as not threadsafe)
188    unsafe {
189        BoxedSystem::with_ref_mut_nonnull(system, |system| {
190            system.run();
191        });
192    }
193}
194
195/// Record a hit on thi Hittr system.
196///
197/// If the sytem is not running, it will enter the failed state.  If it counts 5
198/// or more hits, it will enter the failed.state.
199///
200/// # Safety
201///
202/// The system must be non-NULL and point to a valid hittr_system_t.
203///
204/// ```c
205/// void hittr_system_count_hit(hittr_system_t *system);
206/// ```
207#[no_mangle]
208pub unsafe extern "C" fn hittr_system_count_hit(system: *mut System) {
209    // SAFETY:
210    // - system is not NULL and valid (see docstring)
211    // - system is valid for the life of this function (documented as not threadsafe)
212    // - system will not be accessed during the life of this function (documented as not threadsafe)
213    unsafe {
214        BoxedSystem::with_ref_mut_nonnull(system, |system| {
215            system.count_hit();
216        });
217    }
218}
Source

pub unsafe fn return_val(rval: RType) -> *mut RType

Return a value to C, boxing the value and transferring ownership.

This method is most often used in constructors, to return the built value.

§Safety
  • The caller must ensure that the value is eventually freed.
Examples found in repository?
examples/status.rs (line 127)
124pub unsafe extern "C" fn hittr_system_new() -> *mut System {
125    let sys = System::new();
126    // SAFETY: function docs indicate value must be freed
127    unsafe { BoxedSystem::return_val(sys) }
128}
Source

pub unsafe fn return_val_boxed(rval: Box<RType>) -> *mut RType

Return a boxed value to C, transferring ownership.

This is an alternative to Boxed::return_val for use when the value is already boxed.

§Safety
  • The caller must ensure that the value is eventually freed.
Source

pub unsafe fn to_out_param(rval: RType, arg_out: *mut *mut RType)

Return a value to C, transferring ownership, via an “output parameter”.

If the pointer is NULL, the value is dropped. Use Boxed::to_out_param_nonnull to panic in this situation.

§Safety
  • The caller must ensure that the value is eventually freed.
  • If not NULL, arg_out must point to valid, properly aligned memory for a pointer value.
Examples found in repository?
examples/status.rs (line 145)
142pub unsafe extern "C" fn hittr_system_new_network(system_out: *mut *mut System, port: u16) -> bool {
143    if let Ok(sys) = System::new_network(port) {
144        // SAFETY: see docstring
145        unsafe { BoxedSystem::to_out_param(sys, system_out) }
146        true
147    } else {
148        false
149    }
150}
Source

pub unsafe fn to_out_param_nonnull(rval: RType, arg_out: *mut *mut RType)

Return a value to C, transferring ownership, via an “output parameter”.

If the pointer is NULL, this function will panic. Use Boxed::to_out_param to drop the value in this situation.

§Safety
  • The caller must ensure that the value is eventually freed.
  • arg_out must not be NULL.
  • arg_out must point to valid, properly aligned memory for a pointer value.
Source§

impl<RType: Sized + Default> Boxed<RType>

Source

pub unsafe fn take(arg: *mut RType) -> RType

Take a value from C as an argument.

This function is similar to Boxed::take_nonnull, but returns the default value of RType when given NULL.

§Safety
Source

pub unsafe fn with_ref<T, F: FnOnce(&RType) -> T>(arg: *const RType, f: F) -> T

Call the contained function with a shared reference to the value.

If the given pointer is NULL, the contained function is called with a reference to RType’s default value, which is subsequently dropped.

§Safety
  • No other thread may mutate the value pointed to by arg until this function returns.
  • Ownership of the value remains with the caller.
Source

pub unsafe fn with_ref_mut<T, F: FnOnce(&mut RType) -> T>( arg: *mut RType, f: F, ) -> T

Call the contained function with an exclusive reference to the value.

If the given pointer is NULL, the contained function is called with a reference to RType’s default value, which is subsequently dropped.

§Safety
  • No other thread may access the value pointed to by arg until this function returns.
  • Ownership of the value remains with the caller.

Auto Trait Implementations§

§

impl<RType> Freeze for Boxed<RType>

§

impl<RType> RefUnwindSafe for Boxed<RType>
where RType: RefUnwindSafe,

§

impl<RType> Send for Boxed<RType>
where RType: Send,

§

impl<RType> Sync for Boxed<RType>
where RType: Sync,

§

impl<RType> Unpin for Boxed<RType>
where RType: Unpin,

§

impl<RType> UnwindSafe for Boxed<RType>
where RType: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.