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


    1.创建项目

    rust调用c方式挺多的,这里采用最通俗易懂的方法,用构建脚本进行构建整个项目。

    cargo new rust-to-c
    
    • 1

    2.编辑build.rs的内容

    extern crate cc;
    
    fn main() {
        cc::Build::new().file("src/double.c").compile("libdouble.a");
        cc::Build::new().file("src/third.c").compile("libthird.a");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里的build.rs:若要创建构建脚本,我们只需在项目的根目录下添加一个 build.rs 文件即可。这样一来, Cargo 就会先编译和执行该构建脚本,然后再去构建整个项目。
    导入rust的一个库叫cc,作用肯定就是和c语言调用相关啦,关于具体细节暂时可以不学。
    src/double.c和src/third.c都是一会要写的两个c语言文件,指定好他们编译之后的静态库。

    3.编辑Cargo.toml的内容

    [package]
    name = "rust-to-c"
    version = "0.1.0"
    build = "build.rs"
    
    [dependencies]
    libc = "0.2"
    
    [build-dependencies]
    cc = "1.0"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    package这个地方需要添加上整个构建文件build.rs以告知需要提前构建。
    build-dependencies就是关于build.rs需要的库。
    dependencies是main.rs所需要的库。

    4.两个C语言函数的编辑

    double.c

    int double_input(int input)
    {
        return input * 2;
    }
    
    • 1
    • 2
    • 3
    • 4

    third.c

    int third_input(int input)
    {
        return input * 3;
    }
    
    • 1
    • 2
    • 3
    • 4

    5.编写rust主函数的内容

    extern crate libc;
    
    extern "C" {
        fn double_input(input: libc::c_int) -> libc::c_int;
        fn third_input(input: libc::c_int) -> libc::c_int;
    }
    
    fn main() {
        let input = 4;
        let output = unsafe { double_input(input) };
        let output2: i32 = unsafe { third_input(input) };
        println!("{} * 3 = {}", input, output2);
        println!("{} * 2 = {}", input, output);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    为了在rust代码中和c代码一样的类型定义一致,这里使用了为rust准备的libc库,可以放心使用,不用管两者的类型不一致问题。
    也要提前使用extern “C”来做一个声明,链接主要就是靠它来做一个类似的接口,extern告知Rust编译器这部分功能由一个外部库提供。
    unsafe的作用:rust只能保证自己的代码是安全的,c语言的代码不会给你去做检查,不加unsafe是不行的,涉及到很多底层的操作。

    6.准备就绪,运行

    当上面操作都做完之后,就可以运行了,你可以cargo build之后去执行那个target/debug里面的可执行文件。生成的文件和package的name保持一致。
    当然我们也可以直接cargo run来看到结果。

  • 相关阅读:
    html综合案例2
    TCP三次握手和四次挥手
    函数(1)
    cmd运行jar包,txt文件中文乱码问题
    刷题日常计~JS③
    计算机服务器中了勒索病毒怎么解决,勒索病毒解密步骤数据恢复
    【精品】Spring2.7 采用easysdk方式 整合 aplipay
    对象和数据结构
    Delaunay三角网之逐点插入法(优化版本三)
    第5章 - 二阶多智能体系统的协同控制 --> 连续时间系统编队控制
  • 原文地址:https://blog.csdn.net/phthon1997/article/details/126469708