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

Rust与C接口交互

Rust 对于与其他编程语言的互操作性有着出色的支持。这意味着:

  • 从其他语言调用 Rust 函数。
  • 从 Rust 调用用其他语言编写的函数。

调用C接口库

以windows下Dll库为例。

C库准备

先通过VS生成一个Dll库,对应的C头文件:

#ifdef CEXPORTLIB_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endiftypedef struct {double real;double imag;}Complex;Complex DLL_API add(Complex first, Complex second);//Complex DLL_API add(const Complex& first, const Complex& second);void DLL_API add_self(Complex& first, const Complex& second);
#ifdef __cplusplus
}
#endif

Rust侧调用

1、build脚本

在Cargo.toml中增加build项:

[package]
...
build = "build.rs"

在根目录(Cargo.toml同一层)增加build.rs(里面main与main.rs中的main没任何关系)

// build.rs
fn main() {// println!("cargo::rustc-link-lib=dylib=stdc++"); // This line may be unnecessary for some environment.println!("cargo::rustc-link-search=./x64/Debug"); // lib所在目录
}

2、rust中声明C库中的接口与结构
#[repr©]用于向 Rust 编译器指定这个 struct 总是使用和 C 代码相同的规则来组织内部成员的内存布局。

// c_handle.rs
#[repr(C)]
#[derive(Debug)]
pub struct Complex {pub real: f64,pub imag: f64,
}
#[link(name = "c_export_lib", kind = "dylib")]
unsafe extern "C" {// 此种方式会转移所有权,调用后first与second都无法再访问// pub fn add(first: Complex, second: Complex) -> Complex;// 此种方式不会转移所有权pub fn add(first: *const Complex, second: *const Complex) -> Complex;pub fn add_self(first: *mut Complex, second: *const Complex) -> ();
}

3、rust中调用接口

  let a = c_handle::Complex { real: 1.0, imag: 2.0 };let b = c_handle::Complex { real: 3.0, imag: 4.0 };// let c = unsafe { c_handle::add(a, b) }; // 此种方式后面不能在访问a、blet c = unsafe { c_handle::add(&a, &b) };println!("{:?} + {:?} = {:?}", a, b, c);  let mut d = c_handle::Complex { real: 2.0, imag: 2.0 };unsafe {c_handle::add_self(&mut d, &b);}println!("{:?}", d);

导出C兼容接口

生成C兼容的接口库,用于其他语言调用;先生成库工程:cargo new r_export --lib

1、toml配置

修改cargo.toml增加库说明

[package]
build = "build.rs"[lib]
crate-type = ["cdylib"][dependencies][build-dependencies]
cbindgen = "0.29.0"

2、对外接口

通过pub与extern声明对外兼容接口:

#[repr(C)]
pub struct Point {pub x: i32,pub y: i32,
}
#[unsafe(no_mangle)]
pub extern "C" fn create_point(x: i32, y: i32) -> Point {Point { x, y }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn free_point(point: *mut Point) {unsafe {drop(Box::from_raw(point));}
}
#[unsafe(no_mangle)]
pub extern "C" fn hello_world()
{println!("hello world");
}

3、编写build.rs

在build脚本中设定导出(如头文件等)

// build.rs
use std::env;fn main() {let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();cbindgen::Builder::new().with_crate(crate_dir).generate().expect("Unable to generate bindings").write_to_file("r_export.h");
}

编译成功后,会自动生成C头文件r_export.h,以及dll库。

http://www.dtcms.com/a/434280.html

相关文章:

  • 【C++实战(64)】C++ 邂逅SQLite3:数据库编程实战之旅
  • 泉州网页建站模板开发网址
  • 中华建设杂志网站记者管理网站英文
  • React 18+TS中使用Cesium 1.95
  • View:new关键词干了什么事,还有原型链是什么
  • 如何在新的Spring Boot项目中关闭Spring Security?
  • 药企做网站需要哪些手续国内新闻最新消息今天在线
  • 【Flutter】GetX最佳实践与避坑指南
  • AIFoto 1.15.4 | AI图片工具,AI擦除衣服,变性感衣服
  • 数据合规与ISO标准体系
  • 在Ubuntu22.04系统下安装Jellyfin
  • 福州做网站的app排名优化公司
  • 【Linux系统】快速入门一些常用的基础指令
  • AI自动化测试:接口测试全流程自动化的实现方法——从需求到落地的全链路实践
  • 打开网站建设中是什么意思表白网站制作代码
  • 【MySQL】MVCC:从核心原理到幻读解决方案
  • Unity游戏基础-4(人物移动、相机移动、UI事件处理 代码详解)
  • 神经网络中优化器的作用
  • 电子商务网站建设的流程图什么是软文
  • 【代码管理】git使用指南(新手向)
  • 【大模型】Agent之:从Prompt到Context的演进之路
  • Docker 搭建 Nginx 并启用 HTTPS 具体部署流程
  • 【代码随想录day 34】 力扣 62.不同路径
  • 点击app图标进入网站怎么做小程序软件开发制作
  • 【Rust GUI开发入门】编写一个本地音乐播放器(15. 记录运行日志)
  • Rust模式匹配详解
  • 石家庄做网站建设公司安徽省建设厅网站职称申报
  • gitlab-runner 再次实践中理解和学习
  • C++之stack等容器适配器(上)实战篇
  • JavaWeb零基础学习Day1——HTMLCSS