当前位置: 首页 > news >正文

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

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

判断指针是否为NULL/nullptr

假设存在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
    }
}
复制代码

相关文章:

  • 团队项目的NABCD的分析
  • .net core 依赖注入的基本用发
  • win10驱动下获取cpu信息
  • 闭包--闭包之tab栏切换(四)
  • 单据类报表的制作
  • Spring Boot(1)
  • mac终端常用命令
  • ELK 使用小技巧(第 2 期)
  • Workbook导出excel封装的工具类
  • 勒索病毒防范方案-有韩立刚老师总结的非常规手段
  • js导出excel文件
  • Java枚举比较用equals还是==
  • vue两个组件间值的传递或修改方式
  • 如何在国内构建一个硅谷级的高效技术团队?
  • C#中的结构体与类的区别 (转载)
  • 【译】JS基础算法脚本:字符串结尾
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Codepen 每日精选(2018-3-25)
  • Golang-长连接-状态推送
  • MQ框架的比较
  • Vue ES6 Jade Scss Webpack Gulp
  • Windows Containers 大冒险: 容器网络
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 精彩代码 vue.js
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 微服务框架lagom
  • Semaphore
  • 国内开源镜像站点
  • 如何在招聘中考核.NET架构师
  • (1) caustics\
  • (1)bark-ml
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (42)STM32——LCD显示屏实验笔记
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (剑指Offer)面试题34:丑数
  • (四)Linux Shell编程——输入输出重定向
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转) Android中ViewStub组件使用
  • (转)【Hibernate总结系列】使用举例
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转)可以带来幸福的一本书
  • (转)详解PHP处理密码的几种方式
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NET中的十进制浮点类型,徐汇区网站设计
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @RequestMapping-占位符映射
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ JavaScript ] JSON方法