美文网首页
Windows和MacOS下Rust与C的交互.md

Windows和MacOS下Rust与C的交互.md

作者: Loru_vest | 来源:发表于2020-07-15 15:09 被阅读0次

    本文将分别介绍在WindowsMacOS的环境下,在C中调用Rust的库函数的方法和步骤。

    Windows

    默认你已经安装了Visual Studio 2019 community并勾选了C/C++开发以及Windows 10 SDK的部分

    首先我们要在命令行中使用cl.exe,即MVSC中的C/C++编译器,具体可看这篇文章

    关于Rust的部分

    初始化一个新的库

    > cd Desktop
    > cargo new --lib bridge_c
    

    Cargo.toml中添加

    [lib]
    crate-type = ["cdylib"]
    

    这样,编译后生成的动态链接库xxx.dll可供C调用。

    重新编辑bridge_c/src/lib.rs

    #[no_mangle]
    pub extern "C" fn bridge_c() {
        println!("A hello from Rust :)");
    }
    

    使用cbindgen生成对应的头文件,将bridge.h拖放到桌面上备用

    > cbindgen bridge_c/src/lib.rs -l c > "bridge.h"
    

    上述步骤都完成后,开始编译该库

    > cargo build --release
    

    bridge_c/target/release目录下的bridge_c.dll.libbridge_c.dll拖放到桌面上备用。

    关于C的部分

    Desktop目录下新建一个文件夹hello,把桌面上的bridge.hbridge_c.dll.libbridge_c.dll拖到hello目录下。

    hello目录下新建一个main.c文件,写上:

    #include "bridge.h"
    
    int main(int argc, char const *argv[])
    {
        bridge_c();
        return 0;
    }
    

    接下来开始编译main.c

    > cd hello
    > cl.exe /Iheaders/ bridge_c.dll.lib main.c
    

    运行main.exe

    > main.exe
    A hello from Rust :)
    
    

    如果报错中出现"undefined_symbols"的字样,多半是配置cl.exe时环境变量设置的不对,届时请仔细阅读前述提到的那篇文章。

    MacOS

    默认你已经安装了Xcode的最新版,并且执行过xcode-select --install

    在mac上的交互与上述有些细小的差别。

    关于Rust的部分

    $ cd Desktop
    $ cargo new --lib bridge_c
    

    这次我们使用静态库,即在Cargo.toml中添加

    [lib]
    crate-type = ["lib", "staticlib"]
    

    我们也可以添加依赖,例如

    [dependencies]
    ferris-says = "0.1"
    

    bridge_c/src/lib.rs改为

    use std::io::{stdout, BufWriter};
    
    #[no_mangle]
    pub extern "C" fn hello_devworld() {
        let phrase = b"Hello, /dev/world/2019!";
        let stdout = stdout();
        let mut writer = BufWriter::new(stdout.lock());
        ferris_says::say(phrase, 30, &mut writer).unwrap();
    }
    

    cbindgen生成头文件:

    cbindgen bridge_c/src/lib.rs -l c > "bridge.h"
    

    编译库:

    $ cargo build --release
    

    target/release目录下的libbridge_c.abridge.h拖到桌面上备用

    除此之外,我们还需要一个信息,即在编译C时需要哪些本地库

    $ cargo rustc -- --print native-static-libs
    
    Compiling ...
    note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
    
    note: native-static-libs: -lSystem -lresolv -lc -lm
    
        Finished dev [unoptimized + debuginfo] target(s) in 9.95s
    

    注意note: native-static-libs:后的几个选项,一会儿要用。

    关于C的部分

    $ mkdir hello
    

    libbridge_c.abridge.h拖到hello文件夹中,新建main.c

    $ touch main.c
    

    编辑main.c的内容为:

    #include "bridge.h"
    
    int main() {
        hello_devworld();
        return 0;
    }
    

    编译main.c

    $ cc main.c libbridge_c.a -lSystem -lresolv -lc -lm -o main
    

    运行main

    $ ./main
        ----------------------------------
        | Hello, /dev/world/2019!        |
        ----------------------------------
                    \
                     \
                         _~^~^~_
                     \) /  o o  \ (/
                       '_   -   _'
                       / '-----' \
    

    成功啦~

    参考链接:

    相关文章

      网友评论

          本文标题:Windows和MacOS下Rust与C的交互.md

          本文链接:https://www.haomeiwen.com/subject/hfzdhktx.html