Macro ffi_helpers::null_pointer_check [−][src]
macro_rules! null_pointer_check {
($ptr : expr) => { ... };
($ptr : expr, $null : expr) => { ... };
}
Expand description
Check if we’ve been given a null pointer, if so we’ll return early.
The returned value is the NULL
value for whatever type the calling
function returns. The LAST_ERROR
thread-local variable is also updated
with NullPointer
.
Examples
The typical use case is to call null_pointer_check!()
before doing an
operation with a raw pointer. For example, say a C function passes you a
pointer to some Rust object so it can get a reference to something inside:
struct Foo {
data: Vec<u8>,
}
#[no_mangle]
unsafe extern "C" fn foo_get_data(foo: *const Foo) -> *const u8 {
ffi_helpers::null_pointer_check!(foo);
let foo = &*foo;
foo.data.as_ptr()
}
Because Nullable
is implemented for ()
you can also use the macro as a
cheap way to return early from a function. As an example, destructors are a
common place where you don’t want to do anything if passed a NULL
pointer.
struct Foo {
data: Vec<u8>,
}
#[no_mangle]
unsafe extern "C" fn foo_destroy(foo: *mut Foo) {
ffi_helpers::null_pointer_check!(foo);
let foo = Box::from_raw(foo);
drop(foo);
}
Sometimes when there’s an error you’ll use something different. For example
when writing data into a buffer you’ll usually return the number of bytes
written. Because 0
(the NULL
value for an integer) is typically a
valid number of bytes, you’ll return -1
to indicate there was an error.
The null_pointer_check!()
macro accepts a second argument to allow this.
use libc::{c_char, c_int};
use std::slice;
#[no_mangle]
unsafe extern "C" fn write_message(buf: *mut c_char, length: c_int) -> c_int {
ffi_helpers::null_pointer_check!(buf, -1);
let mut buffer = slice::from_raw_parts_mut(buf as *mut u8, length as usize);
/* write some data into the buffer */
}