C++与Rust操作裸指针的比较

栏目: C · 发布时间: 7年前

内容简介:假设存在由前面可知,Rust提供C接口时返回nullptr或NULL的实现如下将上述C++申请的ptr指针传递到Rust进行写入,最差的办法是在Rust内部创建一个长度相同的

假设存在 const T* ptr1T* 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::copyint_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
    }
}
复制代码

以上所述就是小编给大家介绍的《C++与Rust操作裸指针的比较》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码