C语言和Rust语言的互相调用(1)(C调用Rust)

"本文详细介绍了如何通过C语言调用Rust编写的静态库,包括设置crate_type为staticlib,添加no_mangle和extern"C",以及Cargo.toml配置。最后展示了完整的编译流程和C语言主函数的编写过程。"
摘要由CSDN通过智能技术生成
1.创建项目
cargo new --lib c-to-rust

生成lib.rs文件和Cargo.toml

2.编辑lib.rs的内容

#![crate_type = “staticlib”]
的作用就是指定rustc编译成什么库类型,这里指定为静态库类型。
rustc默认编译产生rust自用的rlib格式库,要让rustc产生动态链接库或者静态链接库,需要显式指定。
方法1: 在文件中指定。
在文件头加上#![crate_type = “foo”], 其中foo的可选类型有bin, lib, rlib, dylib, staticlib.分别对应可执行文件,
默认(将由rustc自己决定), rlib格式,动态链接库,静态链接库。
方法2: 编译时给rustc 传–crate-type参数。参数内容同上。
方法3: 使用cargo,指定crate-type = [“foo”], foo可选类型同1。

#[no_mangle]
的作用是由于rust支持重载,所以函数名会被编译器进行混淆,就像c++一样,加上这个就可以防止重名的错误,不修改函数名。

为了能让rust的函数通过FFI(Foreign Function Interface语言交互接口)被调用,需要加上extern "C"对函数进行修饰。

#![crate_type = "staticlib"]
#[no_mangle]

pub extern "C" fn double_input(input: i32) -> i32 {
    input * 2
}

#[no_mangle]
pub extern "C" fn third_input(input: i32) -> i32 {
    input * 3
}
3.编辑Cargo.toml的内容
[package]
name = "c-to-rust"
version = "0.1.0"

[lib]
name="2_3"
crate-type = ["staticlib"]

这里上面package没啥好说的,就是项目的相关信息。下面的lib和lib.rs同名,name为编译生成之后的lib库的名字,生成lib2_3.a静态库和其他一些编译之后东西。crate-type和上面的那个一样,可以只写在一个地方,一定要写在toml中。

4.rust编译

完成了lib.rs和Cargo.toml之后,就可以进行编译了。
很容易,直接用cargo,也可以写个makefile文件统一完成整个项目。

cargo build

会生成一个target文件,里面有我们需要的东西。

5.C语言主函数的编写

既然是c语言调用rust,那就应该是c语言里写主函数,rust里面的是函数。

#include <stdint.h>
#include <stdio.h>

extern int32_t double_input(int32_t input);
extern int32_t third_input(int32_t input);

int main()
{
    int input = 4;
    int output = double_input(input);
    int output2 = third_input(input);
    printf("%d * 2 = %d\n", input, output);
    printf("%d * 3 = %d\n", input, output2);
    return 0;
}

这里就和写正常C语言代码差不多,有几个地方注意一下,声明一下要使用的rust函数。

6.使用gcc编译C语言代码
gcc -o test_c main.c lib2_3.a -lpthread -ldl

使用gcc编译,-o表示生成test_c可执行文件,需要main.c和lib2_3.a两个文件进行编译。后面的-lpthread和-ldl都是和库的参数。

7.大功告成,直接运行生成的test_c
./test_c

这里的命令还不是很多,如果多的话可以写个makefile文件来统一编译。
直接在文件夹里面make即可,make clean是清除make的结果,非常方便,这里附上代码,关于怎么写网上有很多教程。

ifeq ($(shell uname),Darwin)
    LDFLAGS := -Wl,-dead_strip
else
    LDFLAGS := -Wl,--gc-sections -lpthread -ldl
endif

all: target/c-to-rust
	target/c-to-rust

target:
	mkdir -p $@

target/c-to-rust: target/main.o target/debug/lib2_3.a
	$(CC) -o $@ $^ $(LDFLAGS)

target/debug/lib2_3.a: src/lib.rs Cargo.toml
	cargo build


target/main.o: src/main.c | target
	$(CC) -o $@ -c $<

clean:
	rm -rf target
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RustC语言的相互调用过程中,指针是一个重要的概念。Rust是一种较新的系统级编程语言,具备了内存安全和高性能的特性,而C语言作为一种传统的系统性语言,其指针的概念在Rust中也可以得到支持和使用。 在Rust中,可以使用`ffi`(Foreign Function Interface)功能来与C语言进行交互。这使得Rust可以使用C语言的函数和数据结构。在C语言中,指针用于引用内存中的数据地址。而在Rust中,由于其内存管理的安全性,需要使用特定的语法和关键字来操作和使用指针。 在Rust中,使用`&`和`*`两个符号来进行指针操作。使用`&`可以创建一个指向某个值的引用,并且由Rust自动处理内存的管理。而使用`*`可以通过解引用操作符来取得指针所指向的值。 当RustC语言进行相互调用时,指针在两者之间的传递非常重要。在Rust调用C函数时,需要通过`*const`或`*mut`等类型来声明指针。同时,通过`unsafe`关键字来告诉编译器这是一个不安全的操作,需要手动去管理指针所指向的内存。 在C调用Rust函数时,需要考虑Rust的所有权(ownership)机制。Rust的所有权机制确保了内存的安全和有效的内存管理。当C语言调用Rust函数时,需要传递指针给Rust函数,并在合适的时候将指针的所有权返回给C语言。 总之,RustC语言的相互调用中,指针是连接两者的重要桥梁。在Rust中,通过特定的语法和关键字进行指针操作,并通过`ffi`功能与C语言进行交互。指针的有效管理是确保内存安全的关键所在。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值