Windows 下 c++ 呼叫 Rust 庫的例子

linghuyichong發表於2020-04-27

寫在前面,本文的例子是64位的例子,32位的例子可以參考其他人的文件,在文章末尾有給出。

環境準備

  • 安裝mingw,我的安裝的mingw64,目錄為: D:/tools/mingw64/
  • 安裝rust,此步需要注意,不要選擇預設安裝,應該如下:
    Current installation options:
     default host triple: x86_64-pc-windows-msvc
       default toolchain: stable
                 profile: default
    modify PATH variable: yes
    1) Proceed with installation (default)
    2) Customize installation
    3) Cancel installation
    >2
    I'm going to ask you the value of each of these installation options.
    You may simply press the Enter key to leave unchanged.
    Default host triple?
    x86_64-pc-windows-gnu
    Default toolchain? (stable/beta/nightly/none)
    stable
    Profile (which tools and data to install)? (minimal/default/complete)
    default
    Modify PATH variable? (y/n)
    y
  • 在C:\Users\xxxx\.cargo目錄下,新建config檔案,裡面寫上
    [build]
    target="x86_64-pc-windows-gnu"

rust庫

  • 建立工程
    cargo new mylib --lib
  • 在Cargo.toml中新增
    [dependencies]
    libc = "*"  
    [lib]
    crate-type = ["staticlib"] #靜態庫
    #非常重要:必須要對panic進行標註,否則會出現問題
    [profile.release]
    panic="abort"  
    #非常重要:必須要對panic進行標註,否則會出現問題
    [profile.dev]
    panic="abort"
  • 新增rust原始碼
    //src/lib.rs
    extern crate libc;
    use libc::uint32_t;
    #[no_mangle]
    pub extern "C" fn addition(a: uint32_t, b: uint32_t) -> uint32_t {
      a + b
    }
  • 編譯
    debug版本:
    cargo build
    如果是release版本如下:
    cargo build --release

cpp檔案

  • 原始碼
    //檔名:caller.cpp
    #include <stdio.h>
    #include <stdint.h>
    extern "C" {
       uint32_t
       addition(uint32_t, uint32_t);
    }
    int main(void) {
      uint32_t sum = addition(1, 2);
      printf("%u\n", sum);
      return 0;
    }
  • 編譯
    x86_64-w64-mingw32-g++ -c -o win_cpp_caller.o caller.cpp

編譯生成exe

D:/tools/mingw64/bin/x86_64-w64-mingw32-g++ -static win_cpp_caller.o -o win_cpp_caller -L./mylib/target/x86_64-pc-windows-gnu/debug -lmylib  -ladvapi32 -lws2_32 -luserenv

成功生成win_cpp_caller.exe檔案

總結

本文的例子演示的是64位的例子,32位的例子可以參考文件https://medium.com/csis-techblog/cross-compiling-and-statically-linking-against-rust-libraries-2c02ee2c01af,不過該例子應該也需要在Cargo.toml中新增panic="abort"。
這裡的主要的坑應該就是需要新增panic=”abort”。

當然,網上也有使用msvc編譯的例子,不過貌似也比較麻煩,不出意外的話可能也有坑。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章