文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)
判断指针是否为NULL/nullptr
假设存在const T* ptr1
和T* ptr2
,分别判断它们是否为空,C++和Rust实现如下所示。
- if ((NULL == ptr1) || (nullptr == ptr2)) {
- // do something
- }
- 复制代码
- use std::ptr;
-
- if ptr::null() == ptr1 || ptr::null_mut() == ptr2 {
- // do something
- }
- 复制代码
返回nullptr/NULL
由前面可知,Rust提供C接口时返回nullptr或NULL的实现如下
- #[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);
- }
- }
- 复制代码
使用slice直接读写指针内容
写指针
- const int COUNT = 100;
- int *int_ptr = new int[COUNT];
- for (int i = 0; i < COUNT; ++i) {
- int_ptr[i] = i;
- }
- 复制代码
将上述C++申请的ptr指针传递到Rust进行写入,最差的办法是在Rust内部创建一个长度相同的Vector
,将数据写入Vector
,再通过std::ptr::copy
到int_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);
- }
- }
- 复制代码
上述的tmp_buffers
分配了一块与buffers
等长的新内存,这样多占用了内存,不科学。
使用std::slice
直接读写裸指针可实现前面C++式的做法,示例如下:
- 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;
- }
- }
- }
- 复制代码
进一步,可使用Rust类似C#的foreach进行循环,同时缩小unsafe代码块的影响空间。读指针也可用这个方案。
- 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;
- }
- }
- 复制代码
读指针
- int summary(size_t count, int ptr*) {
- int sum = 0;
- for (int i = 0; i < count; ++i) {
- sum += ptr[i];
- }
- return sum;
- }
- 复制代码
将ptr
传递到Rust进行求和,用slice可以直接操作,避免分配额外的内存,示例如下:
- 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
- }
- }
- 复制代码