当前位置:   article > 正文

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

rust指针和c指针有什么不同

文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)

判断指针是否为NULL/nullptr

假设存在const T* ptr1T* ptr2,分别判断它们是否为空,C++和Rust实现如下所示。

  1. if ((NULL == ptr1) || (nullptr == ptr2)) {
  2. // do something
  3. }
  4. 复制代码
  1. use std::ptr;
  2. if ptr::null() == ptr1 || ptr::null_mut() == ptr2 {
  3. // do something
  4. }
  5. 复制代码

返回nullptr/NULL

由前面可知,Rust提供C接口时返回nullptr或NULL的实现如下

  1. #[no_mangle]
  2. pub extern "C" fn init_engine() -> * const c_void {
  3. // something goes wrong
  4. std::ptr::null()
  5. }
  6. fn main() {
  7. unsafe{
  8. let engine = init_engine();
  9. println!("{:?}", engine);
  10. }
  11. }
  12. 复制代码

使用slice直接读写指针内容

写指针

  1. const int COUNT = 100;
  2. int *int_ptr = new int[COUNT];
  3. for (int i = 0; i < COUNT; ++i) {
  4. int_ptr[i] = i;
  5. }
  6. 复制代码

将上述C++申请的ptr指针传递到Rust进行写入,最差的办法是在Rust内部创建一个长度相同的Vector,将数据写入Vector,再通过std::ptr::copyint_ptr中,示例如下:

  1. use std::ptr;
  2. #[no_mangle]
  3. pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
  4. let mut tmp_buffers = Vec::with_capacity(n);
  5. for index in 0..n {
  6. tmp_buffers.push(index);
  7. }
  8. unsafe {
  9. ptr::copy(tmp_buffers.as_ptr(), buffers, n);
  10. }
  11. }
  12. 复制代码

上述的tmp_buffers分配了一块与buffers等长的新内存,这样多占用了内存,不科学。

使用std::slice直接读写裸指针可实现前面C++式的做法,示例如下:

  1. use std::slice;
  2. #[no_mangle]
  3. pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
  4. unsafe {
  5. let mut slice = slice::from_raw_parts_mut(buffers, n);
  6. for index in 0..n {
  7. slice[index] = index;
  8. }
  9. }
  10. }
  11. 复制代码

进一步,可使用Rust类似C#的foreach进行循环,同时缩小unsafe代码块的影响空间。读指针也可用这个方案。

  1. use std::slice;
  2. #[no_mangle]
  3. pub extern "C" fn write_to_c_buffers(n: usize, buffers: *mut i32) {
  4. let mut buffers = unsafe { slice::from_raw_parts_mut(buffers, n) };
  5. for slice in buffers {
  6. *slice = //do something;
  7. }
  8. }
  9. 复制代码

读指针

  1. int summary(size_t count, int ptr*) {
  2. int sum = 0;
  3. for (int i = 0; i < count; ++i) {
  4. sum += ptr[i];
  5. }
  6. return sum;
  7. }
  8. 复制代码

ptr传递到Rust进行求和,用slice可以直接操作,避免分配额外的内存,示例如下:

  1. use std::slice;
  2. #[no_mangle]
  3. pub extern "C" fn summary_for_c_buffers(n: usize, buffers: *const i32) {
  4. unsafe {
  5. let slice = slice::from_raw_parts(buffers, n);
  6. let mut sum = 0;
  7. for index in 0..n {
  8. sum += slice[index];
  9. }
  10. sum
  11. }
  12. }
  13. 复制代码
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/961194
推荐阅读
相关标签
  

闽ICP备14008679号