我有两个文件:

func.rs

#[no_mangle]
pub extern fn double_input(input: i32) -> i32 { input * 2 }

main.c

#include <stdint.h>
#include <stdio.h>

extern int32_t double_input(int32_t input);

int main() {
   int input = 4;
   int output = double_input(input);
   printf("%d * 2 = %d\n", input, output);
   return 0;
}

我想在Rust中创建静态库,并将库链接到main.c、 我的有效工具链是stable-i686-pc-windows-gnu.我在cmd中这样做:

rustc --crate-type=staticlib func.rs 

但是文件func.lib已经创建,所以我这样做:

gcc -o myprog main.c func.lib -lgcc_eh -lshell32 -luserenv -lws2_32 -ladvapi32

但我有一个错误:

undefined reference to __ms_vsnprintf'

如果我这样做:

rustc --crate-type=staticlib --target=i686-unknown-linux-gnu lib.rs

然后创建libfunc.a,但当我创建时:

gcc -o myprog main.c libfunc.a

我得到一个错误:

main.c:(.text+0x1e): undefined reference to `double_input'

我做错了什么?

推荐答案

TL;DR:安装不同风格的GCC

pacman -R local/gcc
pacman -S mingw-w64-i686-gcc

半知情猜测如下...

在对Rust IRC提供了一些帮助之后,问题似乎在于MSYS2/MinGW gcc是一个"库存"编译器,对MSYS/MinGW/Windows的特殊功能没有专门的了解.

mingw-w64-i686-gcc(或mingw-w64-x86_64-gcc)does知道Windows特定的符号,这是Rust发行版的一部分libbacktrace所需要的.

"正确的"GCC构建应该在gcc --version输出中包含字符串"build by MSYS2 project".


因此,整个过程如下所示:

$ rustc --version --verbose
rustc 1.17.0 (56124baa9 2017-04-24)
host: i686-pc-windows-gnu
$ gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 6.3.0

$ rustc --crate-type=staticlib func.rs
note: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: advapi32
note: library: ws2_32
note: library: userenv
note: library: shell32
note: library: gcc_eh
$ gcc -o main main.c func.lib -ladvapi32 -lws2_32 -luserenv -lshell32 -lgcc_eh
$ ./main
4 * 2 = 8

Rust相关问答推荐

使用nom将任何空白、制表符、白线等序列替换为单个空白

在一个tauri协议处理程序中调用一个rectuc函数的推荐技术是什么?

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

为什么我们需要std::thread::scope,如果我们可以使用thread.join()在函数的生命周期内删除引用?

我如何制作一个变异迭代器来锁定内部数据直到删除?

无法将 rust 蚀向量附加到另一个向量

使用Rust WASM读取文件

如何实现Deref;多次;?

如何对一个特征的两个实现进行单元测试?

在Rust中实现Trie数据 struct 的更好方式

如何获取模块树?

如何基于常量在Rust中跳过一个测试

是否可以通过可变引用推进可变切片?

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

使用 serde_json 进一步处理字段

意外的正则表达式模式匹配

Iterator::collect如何进行转换?

类型组的通用枚举

返回 &str 但不是 String 时,borrow 时间比预期长

为什么 u64::trailing_zeros() 在无分支工作时生成分支程序集?