#1153·cxx

在 Windows 上无法使用 cargo 构建可运行的 DLL

作者: Tim-Evans-Seequent创建于 2023年1月17日更新于 2026年4月27日
标签windowslinking

What I'm trying to do is use CXX and cargo in "cdylib" mode to build my Rust code into a shared library (DLL) that exports the API defined by the extern "Rust" block in my Rust code. My Rust code in lib.rs looks like this:

rust
use cxx::*;

#[derive(Debug)]
pub struct OverflowError {}

impl std::error::Error for OverflowError {}

impl std::fmt::Display for OverflowError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "integer overflow")
    }
}

pub fn add(left: i32, right: i32) -> Result<i32, OverflowError> {
    left.checked_add(right).ok_or(OverflowError {})
}

#[cxx::bridge(namespace = cxx_msvc_shared)]
mod ffi {
    extern "Rust" {
        fn add(left: i32, right: i32) -> Result<i32>;
    }
}
And my `build.rs` looks like this:
```Rust
fn main() {
    cxx_build::bridge("src/lib.rs")
        .flag_if_supported("-std=c++17")
        .compile("cxx_msvc_shared");
    println!("cargo:rerun-if-changed=src/lib.rs");
}
All simple and obvious and it compiles correctly. The generated C++ code for the `add` function looks like this:
```c++
::std::int32_t add(::std::int32_t left, ::std::int32_t right) {
  ::Rust::MaybeUninit<::std::int32_t> return$;
  ::Rust::repr::PtrLen error$ = cxx_msvc_shared$cxxbridge1$add(left, right, &return$.value);
  if (error$.ptr) {
    throw ::Rust::impl<::Rust::Error>::error(error$);
  }
  return ::std::move(return$.value);
}
So I can see that the base function comes from my Rust code and there is a wrapper defined in the C++ to do the error handling. That all look good.