Trait ffizz_passby::PassByPointer
source · [−]pub trait PassByPointer: Sized {
unsafe fn take_from_ptr_arg(arg: *mut Self) -> Self { ... }
unsafe fn from_ptr_arg_ref<'a>(arg: *const Self) -> &'a Self { ... }
unsafe fn from_ptr_arg_ref_mut<'a>(arg: *mut Self) -> &'a mut Self { ... }
unsafe fn return_ptr(self) -> *mut Self { ... }
unsafe fn ptr_to_arg_out(self, arg_out: *mut *mut Self) { ... }
}Expand description
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.
Provided Methods
sourceunsafe fn take_from_ptr_arg(arg: *mut Self) -> Self
unsafe fn take_from_ptr_arg(arg: *mut Self) -> Self
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.
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
sourceunsafe fn from_ptr_arg_ref<'a>(arg: *const Self) -> &'a Self
unsafe fn from_ptr_arg_ref<'a>(arg: *const Self) -> &'a Self
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
sourceunsafe fn from_ptr_arg_ref_mut<'a>(arg: *mut Self) -> &'a mut Self
unsafe fn from_ptr_arg_ref_mut<'a>(arg: *mut Self) -> &'a mut Self
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
Examples found in repository?
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
pub unsafe extern "C" fn hittr_system_run(system: *mut hittr_system_t) {
// SAFETY:
// - system is not NULL and valid (see docstring)
// - system is valid for the life of this function (documented as not threadsafe)
// - system will not be accessed during the life of this function (documented as not threadsafe)
let system = &mut unsafe { hittr_system_t::from_ptr_arg_ref_mut(system) }.0;
system.run();
}
/// Record a hit on thi Hittr system.
///
/// If the sytem is not running, it will enter the failed state. If it counts 5
/// or more hits, it will enter the failed.state.
///
/// # Safety
///
/// The system must be non-NULL and point to a valid hittr_system_t.
#[no_mangle]
pub unsafe extern "C" fn hittr_system_count_hit(system: *mut hittr_system_t) {
// SAFETY:
// - system is not NULL and valid (see docstring)
// - system is valid for the life of this function (documented as not threadsafe)
// - system will not be accessed during the life of this function (documented as not threadsafe)
let system = &mut unsafe { hittr_system_t::from_ptr_arg_ref_mut(system) }.0;
system.count_hit();
}sourceunsafe fn return_ptr(self) -> *mut Self
unsafe fn return_ptr(self) -> *mut Self
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
sourceunsafe fn ptr_to_arg_out(self, arg_out: *mut *mut Self)
unsafe fn ptr_to_arg_out(self, arg_out: *mut *mut 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
Examples found in repository?
142 143 144 145 146 147 148 149 150 151 152 153
pub unsafe extern "C" fn hittr_system_new_network(
system_out: *mut *mut hittr_system_t,
port: u16,
) -> bool {
if let Ok(sys) = System::new_network(port) {
// SAFETY: see docstring
unsafe { hittr_system_t(sys).ptr_to_arg_out(system_out) }
true
} else {
false
}
}