For a list of documents, see: Rust Mobile Complex Graphics Rendering Project Development Series summary (table of Contents)

Check whether the pointer is NULL/nullptr

Suppose const T* ptr1 and T* ptr2 exist and determine whether they are empty, respectively. The C++ and Rust implementations are shown below.

if ((NULL == ptr1) || (nullptr == ptr2)) {
  // do something
}
Copy the code
use std::ptr;

if ptr::null() == ptr1 || ptr::null_mut() == ptr2 {
    // do something
}
Copy the code

Returns the nullptr/NULL

When Rust provides a C interface, nullPTR or NULL is returned

#[no_mangle]
pub extern "C" fn init_engine() - > *const c_void {
    // something goes wrong
    std::ptr::null()
}

fn main() {
    unsafe{
        let engine = init_engine();
        println!("{:? }", engine); }}Copy the code

Use slice to read and write pointer content directly

The write pointer

const int COUNT = 100;
int *int_ptr = new int[COUNT];
for (int i = 0; i < COUNT; ++i) {
    int_ptr[i] = i;
}
Copy the code

The worst way to write to Rust is to create a Vector inside Rust of the same length, write the data to the Vector, and copy it to int_ptr via STD :: PTR :: STD :: PTR :: int_ptr :: STD :: PTR ::

use std::ptr;

#[no_mangle]
pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
    let mut tmp_buffers = Vec::with_capacity(n);
    for index in 0..n {
        tmp_buffers.push(index);
    }
    unsafe{ ptr::copy(tmp_buffers.as_ptr(), buffers, n); }}Copy the code

Tmp_buffers allocates a new block of memory the same length as buffers.

Reading and writing bare Pointers using STD ::slice implements the above C++ approach as shown in the following example:

use std::slice;

#[no_mangle]
pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
    unsafe {
        let mut slice = slice::from_raw_parts_mut(buffers, n);
        for index in 0. n { slice[index] = index; }}}Copy the code

Furthermore, Rust’s C# like foreach can be used for looping while reducing the scope for unsafe code blocks. This scheme is also available for reading Pointers.

use std::slice;

#[no_mangle]
pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
  let mut buffers = unsafe { slice::from_raw_parts_mut(buffers, n) };
  for slice in buffers {
    *slice = //do something; }}Copy the code

Read pointer

int summary(size_t count, int ptr*) {
    int sum = 0;
    for (int i = 0; i < count; ++i) {
        sum += ptr[i];
    }
    return sum;
}
Copy the code

Pass the PTR to Rust for summation, which can be done directly with slice without allocating additional memory, as shown in the following example:

use std::slice;

#[no_mangle]
pub extern "C" fn summary_for_c_buffers(n: usize, buffers: *const i32) {
    unsafe {
        let slice = slice::from_raw_parts(buffers, n);
        let mut sum = 0;
        for index in 0..n {
            sum += slice[index];
        }
        sum
    }
}
Copy the code