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操作裸指针的比较》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

疯狂的独角兽

疯狂的独角兽

丹·莱昂斯 / 王天任 / 海南出版社 / 2017-10 / 42

★商业与文学的有机结合,真实与虚幻间嬉笑怒骂,幽默风趣、引人入胜、发人深省的商业小说。 ★《纽约时报》《华尔街日报》《旧金山纪事报》Amazon畅销书,《财富》《纽约邮报》《新闻周刊》《华盛顿邮报》、畅销书《硅谷钢铁侠》作者阿什利·万斯、畅销书《一网打尽》作者布拉德·斯通联袂推荐。 ★作者丹·莱昂斯集小说家、记者、编剧为一身——HBO经典热门剧、豆瓣高分美剧《硅谷》作者;畅销书《乔布斯......一起来看看 《疯狂的独角兽》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具