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

在现代软件开发中,将不同语言的优势结合起来是一种常见做法。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.so 或 myrust.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 __cplusplusextern "C" {#endifint32_t add_numbers(int32_t a, int32_t b);
ifdef __cplusplus
}
endif
在 C++ 源码中包含该头文件并正常使用:
// main.cpp#include "rust_functions.h"#includeint main() {int result = add_numbers(5, 7);std::cout << "Result from Rust: " << result << std::endl;return 0;}
3. 编译与链接流程
构建过程分为两步:先构建 Rust 库,再编译链接 C++ 程序。
构建 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++如何与Rust进行交互_在C++项目中使用FFI调用Rust代码的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1489147.html
微信扫一扫
支付宝扫一扫