0

0

C++如何与Rust进行交互_在C++项目中使用FFI调用Rust代码

穿越時空

穿越時空

发布时间:2025-12-15 15:48:54

|

668人浏览过

|

来源于php中文网

原创

首先将Rust代码编译为C兼容库,使用no_mangle和extern "C"导出函数;接着在C++中通过头文件声明对应函数并调用;然后在构建时先生成Rust库再链接到C++程序;最后注意处理数据类型时遵循C ABI规则,推荐传递基本类型或repr(C)结构体,字符串操作需手动管理内存,确保资源安全释放。

c++如何与rust进行交互_在c++项目中使用ffi调用rust代码

在现代软件开发中,将不同语言的优势结合起来是一种常见做法。Rust 以其内存安全和高性能著称,而 C++ 在现有项目和生态系统中占据重要地位。通过 FFI(Foreign Function Interface),可以在 C++ 项目中调用 Rust 编写的函数,实现高效、安全的功能模块集成。

1. 将 Rust 代码编译为 C 兼容的静态或动态库

为了让 C++ 能够调用 Rust 代码,首先需要将 Rust 项目构建成一个可供链接的库,并确保其接口符合 C 的调用约定。

Cargo.toml 中配置库类型:

[lib]
crate-type = ["staticlib", "cdylib"]
  • staticlib:生成静态库(如 libmyrust.a),适合直接嵌入到 C++ 可执行文件中。
  • cdylib:生成动态共享库(如 libmyrust.somyrust.dll),适用于运行时加载。

使用 #[no_mangle]extern "C" 确保函数符号不被修饰并使用 C 调用约定:

立即学习C++免费学习笔记(深入)”;

// src/lib.rs
#[no_mangle]
pub extern "C" fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}

2. 在 C++ 中声明并调用 Rust 函数

C++ 需要知道如何调用这些来自 Rust 的函数。为此,需编写对应的 C 风格函数声明。

创建头文件 rust_functions.h

#ifdef __cplusplus
extern "C" {
#endif

int32_t add_numbers(int32_t a, int32_t b);

ifdef __cplusplus

}

endif

在 C++ 源码中包含该头文件并正常使用:

// main.cpp
#include "rust_functions.h"
#include 

int main() { int result = add_numbers(5, 7); std::cout << "Result from Rust: " << result << std::endl; return 0; }

3. 编译与链接流程

构建过程分为两步:先构建 Rust 库,再编译链接 C++ 程序。

虎课网
虎课网

虎课网是超过1800万用户信赖的自学平台,拥有海量设计、绘画、摄影、办公软件、职业技能等优质的高清教程视频,用户可以根据行业和兴趣爱好,自主选择学习内容,每天免费学习一个...

下载
  • 构建 Rust 库:
    cargo build --release
    生成的库位于 target/release/ 目录下。
  • 编译 C++ 并链接 Rust 库:
    假设使用 GCC 或 Clang:
g++ main.cpp \
  -L./target/release \
  -lmyrust \
  -o myapp \
  -fPIC

注意:如果遇到链接错误,可能需要手动指定 Rust 工具链的 runtime 库路径,或使用 -l:libmyrust.a 显式指定文件名。

4. 处理复杂数据类型的注意事项

Rust 和 C++ 对对象布局、所有权和生命周期的管理方式不同,传递结构体或字符串时要格外小心。

推荐做法是尽量通过基本类型或 C 兼容结构通信:

#[repr(C)]
pub struct Point {
    pub x: f64,
    pub y: f64,
}

[no_mangle]

pub extern "C" fn distance_from_origin(p: Point) -> f64 { (p.x p.x + p.y p.y).sqrt() }

C++ 端对应声明:

struct Point {
    double x;
    double y;
};

extern "C" double distance_from_origin(Point p);

对于字符串,建议使用 const char* 并由调用方负责内存管理:

use std::ffi::CString;

[no_mangle]

pub extern "C" fn greet(name: const i8) -> mut i8 { let c_str = unsafe { std::ffi::CStr::from_ptr(name) }; let name_str = c_str.to_str().unwrap_or("Unknown"); let output = format!("Hello, {}!", name_str); CString::new(output).unwrap().into_raw() }

// 必须提供释放函数

[no_mangle]

pub extern "C" fn free_c_string(s: *mut i8) { if !s.isnull() { unsafe { let = CString::from_raw(s); } } }

C++ 使用示例:

extern "C" {
    char* greet(const char* name);
    void free_c_string(char* s);
}

// ...

const char input = "Alice"; char result = greet(input); std::cout << result << std::endl; free_c_string(result); // 避免内存泄漏

基本上就这些。只要遵守 C ABI 规则,控制好数据流动和资源生命周期,C++ 项目就能安全有效地利用 Rust 实现关键功能。这种方式特别适合性能敏感或安全性要求高的模块替换与增强。不复杂但容易忽略的是链接顺序和运行时依赖处理,建议配合脚本或构建系统(如 CMake)自动化整个流程。

相关专题

更多
C++系统编程内存管理_C++系统编程怎么与Rust竞争内存安全
C++系统编程内存管理_C++系统编程怎么与Rust竞争内存安全

C++系统编程中的内存管理是指 对程序运行时内存的申请、使用和释放进行精细控制的机制,涵盖了栈、堆、静态区等不同区域,开发者需要通过new/delete、智能指针或内存池等方式管理动态内存,以避免内存泄漏、野指针等问题,确保程序高效稳定运行。它核心在于开发者对低层内存有完全控制权,带来灵活性,但也伴随高责任,是C++性能优化的关键。

10

2025.12.22

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

306

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

526

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

209

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1468

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

620

2023.11.24

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号