back

链接rust cxx编译的静态库

created 2025-11-04

cxx 为 Rust 和 C++ 之间提供一个 C ABI 的抽象层,能方便两端互操作

cxx

环境

然後是 cargo 全局设置和项目内设置,需求是 rust 编译成库,供 C++ 的应用程序单向调用。

# .cargo/config.toml
[target.x86_64-pc-windows-msvc]
rustflags = ["-Ctarget-feature=+crt-static"]

# cargo.toml
[dependencies]
cxx = "1.0.187"
[build-dependencies]
cxx-build = "1.0.187"
[lib]
name = "mylib"
crate-type = ["staticlib"]

Rust 端编译成库

// /src/lib.rs
#[cxx::bridge]
mod ffi {
    extern "Rust" {
        fn add(a: i32, b: i32) -> i32;
    }
}
pub fn add(a: i32, b: i32) -> i32 {
    return a + b;
}

cxx-build 能生成对应的 API 头文件,不用自己管理了,挺方便。

// /build.rs
fn main() {
    cxx_build::bridge("src/lib.rs")
        .std("c++17")
        .compile("libname");
}

cargo build 编译完成后,cxx-build 把输出的头文件放到了 /target/cxx-bridge/<your_project_name>/src/

// lib.rs.h
#pragma once
#include <cstdint>

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
#endif // __clang__

::std::int32_t add(::std::int32_t a, ::std::int32_t b) noexcept;

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__

应用程序引入库

VS 这边打开项目属性(Project -> Properties)里的额外头文件选项(C/C++ -> General-> Additional Include Directories)填入刚刚 cxx-build 生成的那个头文件。

然後是链接器选项(Linker),常规(general)这一栏里的附加库路径(Additional Library Directories)填入刚编译出来的库的路径;输入(Input)这一栏的附加依赖(Additional Dependencies)填入库的名字 以及库所需的依赖

比如我的库因为缺依赖而报错:

1>WinMain.cpp
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_GetUserProfileDirectoryW referenced in function _ZN3std3env8home_dir17h6c89df485a47e1a9E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtReadFile referenced in function _ZN3std2io19default_read_to_end17hc5fdbdf1f63dca51E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_RtlNtStatusToDosError referenced in function _ZN3std2io19default_read_to_end17hc5fdbdf1f63dca51E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_freeaddrinfo referenced in function _ZN3std3net11socket_addr19resolve_socket_addr17h3dc637bfba6a58ceE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_closesocket referenced in function _ZN3std3net3tcp9TcpStream15connect_timeout17h3455acd4a2df04a1E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_shutdown referenced in function _ZN3std3net3tcp9TcpStream8shutdown17h4999a3b28594f652E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSAGetLastError referenced in function _ZN3std3net3tcp9TcpStream8shutdown17h4999a3b28594f652E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_setsockopt referenced in function _ZN3std3net3udp9UdpSocket16set_read_timeout17h833633e5882d4286E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_getsockopt referenced in function _ZN3std3net3udp9UdpSocket12read_timeout17hf265e7ff2d55f38bE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_recv referenced in function _ZN3std3net3udp9UdpSocket4peek17he173f86c810480caE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSARecv referenced in function _ZN58_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Read$GT$13read_vectored17hceae447ca24246d2E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSASend referenced in function _ZN59_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$14write_vectored17h7e899adad0631f2fE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_send referenced in function _ZN63_$LT$$RF$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$5write17h42cca07bb3fb7182E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_accept referenced in function _ZN3std3net3tcp11TcpListener6accept17h203dd8c4a591a7afE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_ioctlsocket referenced in function _ZN3std3net3udp9UdpSocket15set_nonblocking17h57f8a5604ec7e53dE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_getpeername referenced in function _ZN3std3net3udp9UdpSocket9peer_addr17hf812d96a2f614f57E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSADuplicateSocketW referenced in function _ZN3std2os7windows2io6socket14BorrowedSocket18try_clone_to_owned17ha000ed72d3fede88E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSASocketW referenced in function _ZN3std2os7windows2io6socket14BorrowedSocket18try_clone_to_owned17ha000ed72d3fede88E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_getaddrinfo referenced in function _ZN3std3sys3pal6common14small_c_string24run_with_cstr_allocating17h446730d046dc4957E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtWriteFile referenced in function _ZN3std3sys3pal7windows6handle6Handle17synchronous_write17h66436be2b3f10b23E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtOpenFile referenced in function _ZN3std3sys3pal7windows4pipe9anon_pipe17h82c513f72568a06dE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_NtCreateNamedPipeFile referenced in function _ZN3std3sys3pal7windows4pipe9anon_pipe17h82c513f72568a06dE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_connect referenced in function _ZN3std3sys3net10connection6socket9TcpStream7connect17he6ba9098d314307eE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_bind referenced in function _ZN3std3sys3net10connection6socket11TcpListener4bind17had1acf683e966fdeE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_listen referenced in function _ZN3std3sys3net10connection6socket11TcpListener4bind17had1acf683e966fdeE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_getsockname referenced in function _ZN3std3sys3net10connection6socket11TcpListener11socket_addr17h0052736427b085daE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_sendto referenced in function _ZN3std3sys3net10connection6socket9UdpSocket7send_to17h82a11d834f21400fE
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSAStartup referenced in function _ZN3std3sys3net10connection6socket7windows11wsa_startup17hf19aa8ea99826c91E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_WSACleanup referenced in function _ZN3std3sys3net10connection6socket7windows11wsa_startup17hf19aa8ea99826c91E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_select referenced in function _ZN3std3sys3net10connection6socket7windows6Socket15connect_timeout17hff6772d4d642e406E
1>mylib.lib(std-5740e47ddabbb05c.std.6c5d1f3eac284022-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol __imp_recvfrom referenced in function _ZN3std3sys3net10connection6socket7windows6Socket20recv_from_with_flags17h5929f5d1004ffc43E

添加相应的库 Ws2_32.lib、Userenv.lib 和 Ntdll.lib,即可解决。

Linker