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

【CXX】1 CXX主要概念概览

本文描述了CXX(一个用于在Rust和C++之间进行桥接的库)中的关键概念,特别是FFI(外部函数接口)边界所涉及的三种主要类型:共享结构体、不透明类型和函数。

一、示例代码

#[cxx::bridge]
mod ffi {// 任何共享结构,其字段对两种语言都是可见的。struct BlobMetadata {size: usize,tags: Vec<String>,}extern "Rust" {// 两种语言都可以传递零个或多个不透明类型,但只有Rust可以看到这些字段。type MultiBuf;// 在Rust中实现的函数。fn next_chunk(buf: &mut MultiBuf) -> &[u8];}unsafe extern "C++" {// 一个或多个C++匹配的头文件,其中包含封闭的extern "C++"块。我们的代码生成器不会读取它,但它会被#included并用于静态断言中,以确保我们对FFI边界的理解是准确的。//在extern "C++"部分,我们列出了C++为事实来源的类型和函数,以及声明这些API的头文件。将来这部分可能会从头文件中生成,但目前我们需要写出签名;静态断言会验证它们的准确性。include!("demo/include/blobstore.h");// 两种语言都可以传递零个或多个不透明类型,但只有C++可以看到这些字段。type BlobstoreClient;// 用C++实现的函数。fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;fn put(&self, parts: &mut MultiBuf) -> u64;fn tag(&self, blobid: u64, tag: &str);fn metadata(&self, blobid: u64) -> BlobMetadata;}
}

二、FFI边界所涉及的三种主要类型

  1. 共享结构体(Shared Structs)
  • 定义:共享结构体是那些在Rust和C++中字段都可见的数据结构。
  • 用途:当两种语言都需要访问结构体的字段时,使用共享结构体。
  • 实现:通常在Rust中定义这些结构体,并通过cxx::bridge宏将其暴露给C++。这允许两种语言以一致的方式访问和操作这些数据结构。
  • 示例:在示例中,BlobMetadata是一个共享结构体,它包含了size和tags字段,这些字段在Rust和C++中都是可见的。
  1. 不透明类型(Opaque Types)
  • 定义:不透明类型的字段对另一种语言是保密的。
  • 用途:当一种语言需要引用另一种语言中定义的复杂类型,但不希望暴露其内部实现时,使用不透明类型。
  • 实现:这些类型通常通过引用(如Rust的&、Box或C++的unique_ptr)在FFI中传递。
  • 示例:在示例中,MultiBuf和BlobstoreClient都是不透明类型。在Rust中,MultiBuf的字段对C++是保密的,同样,BlobstoreClient的字段对Rust也是保密的。
  1. 函数(Functions)
  • 定义:函数可以在任意一种语言中实现,然后从另一种语言中调用。
  • 用途:函数是实现Rust和C++之间交互的核心机制。
  • 实现:在cxx::bridge宏中,通过extern "Rust"和extern "C++"块分别列出Rust和C++中实现的函数。
  • 示例:在示例中,next_chunk函数在Rust中实现,并从C++中调用;而new_blobstore_client、put、tag和metadata函数在C++中实现,并从Rust中调用。

三、CXX库的设计特点

  • 有限制性和有观点的:CXX库不是设计为处理所有可能的Rust和C++签名,而是专注于提供一套能够做出安全保证的功能。
  • 需要练习:由于CXX桥接不会以所有可能习惯的方式工作,因此有效地使用它可能需要一些实践和学习。

四、使用注意事项

  • 静态断言:在extern "C++"部分,CXX自动使用静态断言来验证签名的准确性,这有助于确保FFI边界的理解是一致的。
  • 父模块引用:在extern "Rust"部分列出的类型和函数隐含地引用了CXX的父模块。这通常通过相关的use语句来实现。

五、总结

CXX库为Rust和C++之间的桥接提供了一个强大的框架,通过共享结构体、不透明类型和函数等机制,允许两种语言之间进行高效、安全的交互。理解这些关键概念是使用CXX库的基础。

相关文章:

【CXX】1 CXX主要概念概览

本文描述了CXX&#xff08;一个用于在Rust和C之间进行桥接的库&#xff09;中的关键概念&#xff0c;特别是FFI&#xff08;外部函数接口&#xff09;边界所涉及的三种主要类型&#xff1a;共享结构体、不透明类型和函数。 一、示例代码 #[cxx::bridge] mod ffi {// 任何共享…...

PyQT项目如何在Linux中自启显示界面

可以通过systemd服务启动PyQt程序 1. 创建服务文件&#xff1a; 在 /etc/systemd/system/ 目录下创建一个新的服务文件。例如&#xff0c;如果您的程序名为 my_program.py&#xff0c;可以创建一个名为 my_program.service 的文件&#xff1a; sudo nano /etc/systemd/system…...

【信息系统项目管理师-案例真题】2019下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题 1】(6 分)【问题 2‍ 】(8 分)【问题 3‍ 】(11 分)试题二【问题 1】‍(5分)【问题 2】‍ (14 分)【问题 3‍ 】(6 分)试题三【问题 1】(8 分)【问题 2‍ 】(6 分)【问题 3】‍ (8 分)【问题 4‍ …...

DeepSeek 助力 Vue 开发:打造丝滑的返回顶部按钮(Back to Top)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

【前端开发学习笔记15】Vue_8

手动添加Pinia到Vue项目&#xff1a; 在实际开发中&#xff0c;Pinia配置可在项目创建时自动添加。初次学习从零开始&#xff1a; 1. 用Vite创建空的Vue3项目&#xff0c;命令为npm create vuelatest。 2. 按官方文档将pinia安装到项目中。 import { createApp } from vue im…...

deepin linux UOS AI 使用 deepseek-r1 30B

我们用 ollama 下载 deepseek-r1 3B 执行命令: $ ollama pull models/unsloth/DeepSeek-R1-Distill-Qwen-32B-GGUF 下载完成后 我们就要重新更改目录和文件了 deepseek-r1/gguf (这是目录结构) 然后我把 gguf文件 更名成 DeepSeek-R1.gguf (就是目录下最大的那个文件) …...

通过docker启用rabbitmq插件

创建文件&#xff0c;docker-compose.yml services:rabbitmq:image: rabbitmq:4.0-managementports:- "5672:5672"- "15672:15672"volumes:- ./data/rabbitmq/data:/var/lib/rabbitmq # 持久化数据- ./data/rabbitmq/plugins/rabbitmq_delayed_message_ex…...

对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 与基于 openEuler 构建 LVS-DR 群集

一、 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式&#xff0c;比较其各自的优势 NAT 模式 部署简单&#xff1a;NAT 模式下&#xff0c;所有的服务器节点只需要连接到同一个局域网内&#xff0c;通过负载均衡器进行网络地址转换&#xff0c;就可以实现负载均衡功能。不需要对…...

C++17 中 std::lcm:从入门到精通

文章目录 一、引言二、std::lcm 的基本概念三、入门示例四、计算多个整数的最小公倍数五、std::lcm 的实现原理六、在实际项目中的应用七、注意事项八、总结 一、引言 在 C 编程中&#xff0c;处理数学运算时&#xff0c;计算最小公倍数&#xff08;Least Common Multiple&…...

html 点击弹出视频弹窗

一、效果: 点击视频按钮后,弹出弹窗 播放视频 二、代码 <div class="index_change_video" data-video-src="</...

docker安装mongo,导入、导出数据

1、docker安装mongo docker pull mongo docker run -d -p 27017:27017 --name mongodb mongodocker update mongodb --restartalways ## 开机自启动-d&#xff1a;表示以后台模式运行容器。 -p 27017:27017&#xff1a;将容器内部的 MongoDB 默认端口 27017 映射到宿主机的 27…...

代码随想录算法【Day44】

Day44 1143.最长公共子序列 class Solution { public:int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size() 1, vector<int>(text2.size() 1, 0));for (int i 1; i < text1.size(); i) {for (int j 1; …...

项目总结:java agent的使用

测试团队会做java agent的事&#xff0c;实现测试模拟&#xff0c;各种数据采集等等工作&#xff0c;而这些不需要开发改代码来做到&#xff0c;只需要挂载下agent。 目录 javaagent认识和例子代码例子&#xff1a;java.lang.instrument自定义实现一个javaagentagent jar测试 回…...

使用 LangChain 对接硅基流动(SiliconFlow)API:构建一个智能对话系统

文章目录 什么是硅基流动&#xff08;SiliconFlow&#xff09;&#xff1f;LangChain 简介在 LangChain 中对接硅基流动步骤 1&#xff1a;安装必要的库步骤 2&#xff1a;设置 API 密钥步骤 3&#xff1a;编写代码代码解析步骤 4&#xff1a;运行代码如何扩展和改进总结 在现代…...

如何借助NoETL指标平台实现数据分析、决策的提效?

通常&#xff0c;企业通过明确分析目标、定位所需分析的数据&#xff0c;再通过多渠道汇集销售数据、客户反馈、市场调研等信息&#xff0c;经过数据清洗、缺失值处理及格式标准化等手段&#xff0c;运用描述性统计、回归分析、聚类分析及关联规则挖掘等多样分析方法&#xff0…...

Java--IO流详解 (上)--字符流

目录 IO流的概念 字符流 输入流 Reader核心方法 1.close() 2.mark(int readAheadLimit) 3.markSupported() 4.read() 5.read(char[] cbuf) 6.read(char[] cbuf, int off, int len) 7.read(CharBuffer target) 8.ready() 9.reset() 10.skip(long n) Reader 的常用…...

大模型语言简介

大模型语言能做什么 信息提取 将长段文字中的信息抽取出来并且以结构化的方式输出。相比起传统NLP的方式&#xff0c;大模型在泛化能力上有非常大的提升&#xff0c;并且开发成本要低2个数量级。应用场景包括&#xff1a;论文论点论据提取、用户画像提取、舆情分析、病例结构…...

手动配置IP

手动配置IP&#xff0c;需要考虑四个配置项&#xff1a; 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址&#xff1a;格式表现为点分十进制&#xff0c;如192.168.254.1 子网掩码&#xff1a;用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...

Golang 进阶训练营

一、Golang 的 slice、map、channel 1.1 slice vs array a : make([]int, 100) //切片 b : [100]int{} //数组array需指明长度&#xff0c;长度为常量且不可改变 array长度为其类型中的组成部分&#xff08;给参数为长度100的数组的方法传长度为101的会报错&#xff09; array在…...

2-使用wifidog实现portal

wifidog是openwrt上面实现portal认证的一个开源工具&#xff0c;从网关端到服务器都帮你搭建好&#xff0c;通过学习wifidog的原理&#xff0c;后面就可以改造成自己需要的逻辑。 1. openwrt安装wifidog 添加源 vim 14.07/feeds.conf.defaultsrc-git wifidog https://github.c…...

Spring Boot + ShardingSphere 踩坑记

最近在准备秋招&#xff0c;偷了个轮子项目之后想改个分表&#xff0c;于是有了这篇文章。 省流&#xff1a;请使用shardingsphere-jdbc 5.5.2&#xff0c;并根据官方5.5.2版本文档进行配置&#xff0c;不要使用starter。此外&#xff0c;如果希望使用INTERVAL分片算法&#x…...

AI时代前端开发的创造力:解放还是束缚?

在人工智能&#xff08;AI&#xff09;快速发展的时代&#xff0c;AI技术的影响已经渗透到各个领域&#xff0c;从医疗保健到金融服务&#xff0c;再到创意产业。AI工具的出现&#xff0c;为前端开发带来了前所未有的效率提升&#xff0c;但也引发了人们对创造力的担忧&#xf…...

有哪些免费的SEO软件优化工具

随着2025年互联网的不断发展&#xff0c;越来越多的企业意识到在数字营销中&#xff0c;网站的曝光度和排名至关重要。无论是想要提高品牌知名度&#xff0c;还是想要通过在线销售增加收益&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;都是一项不可忽视的关键策略。而要…...

FastExcel + Java:打造高效灵活的Excel数据导入导出解决方案

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 基于AOP的数据字典实现…...

在Vue中,JavaScript数组常用方法,添加,插入,查找,删除等整理

在Vue中&#xff0c;JavaScript数组常用&#xff0c;添加&#xff0c;插入&#xff0c;查找&#xff0c;删除等整理 1.splice()方法可以直接修改原数组&#xff0c;通过指定要删除元素的索引来删除它。 例&#xff1a; let index // 要删除的元素的索引; this.array.splice(i…...

vue知识点2

1.methods和mounted的区别 methods是定义方法&#xff0c;不涉及到调用 mounted涉及到操作 所以methods后面是&#xff1a;&#xff0c;mounted后面是&#xff08;&#xff09; 2.介绍一下emit的用法 如果子控件要调用父页面的方法&#xff0c;在父页面的子控件引用处&…...

node.js + html调用ChatGPTApi实现Ai网站demo(带源码)

文章目录 前言一、demo演示二、node.js 使用步骤1.引入库2.引入包 前端HTML调用接口和UI所有文件总结 前言 关注博主&#xff0c;学习每天一个小demo 今天是Ai对话网站 又到了每天一个小demo的时候咯&#xff0c;前面我写了多人实时对话demo、和视频转换demo&#xff0c;今天…...

14.Python生成器、迭代器、闭包、装饰器、元类、垃圾回收、内建函数

在 Python 中&#xff0c;生成器、迭代器、闭包、装饰器、元类、垃圾回收和内建函数是一些重要的概念和功能&#xff0c;它们对于编写高效、灵活的代码非常重要。下面我们逐一详细介绍这些概念及其用法。 1. 生成器&#xff08;Generator&#xff09; 生成器是一个函数&#…...

STM32+Proteus+DS18B20数码管仿真实验

1. 实验准备 硬件方面&#xff1a; 了解 STM32 单片机的基本原理和使用方法&#xff0c;本实验可选用常见的 STM32F103 系列。熟悉 DS18B20 温度传感器的工作原理和通信协议&#xff08;单总线协议&#xff09;。数码管可选用共阴极或共阳极数码管&#xff0c;用于显示温度值。…...

Vulhub靶机 ActiveMQ 反序列化漏洞(CVE-2015-5254)(渗透测试详解)

一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本&#xff1a;Apache ActiveMQ 5.x ~ Apache ActiveMQ 5.13.0 二、访问靶机IP 8161端口 默认账户密码 admin/admin&#xff0c;登录 此时qucues事件为空 1、使用jmet-0.1.0-all.jar工具将…...