如何导出C静态库中的函数以在Windows平台上供Rust链接调用?
问题根源
你遇到的问题本质是两个:
__declspec(dllexport)仅在编译Windows动态库时生效,编译静态库时添加该标识不会将函数加入静态库的公开符号表。- 你使用
dumpbin /exports查看静态库符号是错误用法,该参数仅适用于动态库和动态库的导入库,静态库的符号需要用dumpbin /symbols查看。
可行解决方案
1. 修改C语言导出宏
区分动态库、静态库编译场景调整宏定义:
// Note this is compiled with CMake to generate both a DyLib and a Static Lib. #if defined(BUILD_SHARED_LIBS) // 仅编译动态库时启用dllexport #define EXPORT __declspec (dllexport) #else // 编译静态库时留空,符号默认会保留到静态库中 #define EXPORT #endif EXPORT int my_func (void) { return 3; }
2. 调整CMake配置
避免动态库的导入库和静态库重名导致Rust链接时找错文件:
# 动态库目标 add_library(my_lib_shared SHARED my_lib.c) set_target_properties(my_lib_shared PROPERTIES OUTPUT_NAME "my_lib") # 静态库目标 add_library(my_lib_static STATIC my_lib.c) set_target_properties(my_lib_static PROPERTIES OUTPUT_NAME "my_lib_static")
编译后会得到my_lib.dll+my_lib.lib(动态库的导入库)、my_lib_static.lib(真正的静态库)三个文件。
3. 调整Rust侧链接配置
lib.rs修改
显式指定静态链接,同时补充extern "C"声明调用约定:
#[cfg (test)] mod tests; // No *-sys crate for simplicity pub mod sys { // 显式指定链接静态库、调用约定为C #[link (name = "my_lib_static", kind = "static")] extern "C" { pub fn my_func () -> i32; } }
build.rs无需修改,只要搜索路径指向静态库所在目录即可。
4. 验证静态库符号
编译完成后执行以下命令验证静态库是否包含对应符号:
dumpbin /symbols path/to/my_lib_static.lib | findstr "my_func"
能搜到对应条目即可正常链接。
内容的提问来源于stack exchange,提问作者Rafaelplayerxd YT
相关产品推荐
相关产品推荐

