1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
/// This trait supports values passed to Rust by pointer.
/// These values are represented as in C, and always handled as pointers.
///
/// Typically PassByPointer is used to model objects managed entirely by Rust. These are
/// represented in the C API by a pointer to an opaque struct, with "new" and "free" functions
/// handling creation and destruction.
pub trait PassByPointer: Sized {
/// Take a value from C as an argument.
///
/// This function is typically used to handle arguments passed from C, but because it takes
/// ownership of the passed value, while leaving the C code with a pointer, it can lead to
/// use-after-free errors if not used carefully. It is most common in "free" functions,
/// but can also be used in contexts where it is clearl that the called function consumes
/// the value. For example, a database connections's `execute` method might reasonably
/// consume a query argument.
///
/// ```c
/// 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
/// - arg must be a value returned from Box::into_raw (via return_ptr or ptr_to_arg_out)
/// - arg becomes invalid and must not be used after this call
unsafe fn take_from_ptr_arg(arg: *mut Self) -> Self {
debug_assert!(!arg.is_null());
// SAFETY: see docstring
unsafe { *(Box::from_raw(arg)) }
}
/// Borrow a value from C as an argument.
///
/// This represents an immutable (shared) borrow. Use `from_ptr_arg_ref_mut` for
/// mutable (exclusive) borrows. The safety requirements of the two methods differ
/// slightly: this method requires that the value not be concurrently modified, while
/// `from_ptr_arg_ref_mut` requires that the value not be accessed at all.
///
/// # Safety
///
/// - arg must not be NULL
/// - *arg must be a valid instance of Self
/// - arg must be valid for the lifetime assigned by the caller
/// - arg must not be modified by anything else during that lifetime
unsafe fn from_ptr_arg_ref<'a>(arg: *const Self) -> &'a Self {
debug_assert!(!arg.is_null());
// SAFETY: see docstring
unsafe { &*arg }
}
/// Mutably borrow a value from C as an argument.
///
/// Because this is a mutable (exclusive) reference, the C caller must ensure
/// that no other threads _access_ the contained value during the lifetime of
/// this reference. This includes read-only access
///
/// # Safety
///
/// - arg must not be NULL
/// - *arg must be a valid instance of Self
/// - arg must be valid for the lifetime assigned by the caller
/// - arg must not be accessed by anything else during that lifetime
unsafe fn from_ptr_arg_ref_mut<'a>(arg: *mut Self) -> &'a mut Self {
debug_assert!(!arg.is_null());
// SAFETY: see docstring
unsafe { &mut *arg }
}
/// Return a value to C, 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
unsafe fn return_ptr(self) -> *mut Self {
Box::into_raw(Box::new(self))
}
/// Return a value to C, transferring ownership, via an "output parameter".
///
/// # 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
unsafe fn ptr_to_arg_out(self, arg_out: *mut *mut Self) {
debug_assert!(!arg_out.is_null());
// SAFETY: see docstring
unsafe { *arg_out = self.return_ptr() };
}
}