crm开发定制C语言和Rust语言的互相调用(1)(C调用Rust)

1.创建项目

cargo new --lib c-to-rust
  • 1

生成lib.rs文件和Cargo.toml

2.编辑lib.rs的内容

#![crate_type = “staticlib”]
crm开发定制的作用就是指定rustccrm开发定制编译成什么库类型,crm开发定制这里指定为静态库类型。
rustccrm开发定制默认编译产生自用的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}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.编辑Cargo.toml的内容

[package]name = "c-to-rust"version = "0.1.0"[lib]name="2_3"crate-type = ["staticlib"]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

4.rust编译

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

cargo build
  • 1

会生成一个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\", input, output);    printf("%d * 3 = %d\", input, output2);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

6.使用gcc编译C语言代码

gcc -o test_c main.c lib2_3.a -lpthread -ldl
  • 1

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

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

./test_c
  • 1

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

ifeq ($(shell uname),Darwin)    LDFLAGS := -Wl,-dead_stripelse    LDFLAGS := -Wl,--gc-sections -lpthread -ldlendifall: target/c-to-rust	target/c-to-rusttarget:	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 buildtarget/main.o: src/main.c | target	$(CC) -o $@ -c $<clean:	rm -rf target
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发