Visual studio Rust代码无法链接到Windows上编译的C库,因为存在未解析的外部符号
我一直试图让Rust与Windows上的C库链接,但Rust找不到我需要的函数。看起来我的函数签名是错误的,但是Rust可以找到Visual studio Rust代码无法链接到Windows上编译的C库,因为存在未解析的外部符号,visual-studio,compiler-errors,linker,rust,ffi,Visual Studio,Compiler Errors,Linker,Rust,Ffi,我一直试图让Rust与Windows上的C库链接,但Rust找不到我需要的函数。看起来我的函数签名是错误的,但是Rust可以找到.lib文件 我把它缩小到了非常简单的C和Rust代码,但仍然不知道如何让它工作: test.c——使用Visual Studio 2015编译 \ifdef\uuucplusplus 外部“C” { #恩迪夫 #包括 typedef结构MyStruct{ int32_t i; }我的结构; MyStruct my_func(const MyStruct*s){ 我的结
.lib
文件
我把它缩小到了非常简单的C和Rust代码,但仍然不知道如何让它工作:
test.c——使用Visual Studio 2015编译
\ifdef\uuucplusplus
外部“C”
{
#恩迪夫
#包括
typedef结构MyStruct{
int32_t i;
}我的结构;
MyStruct my_func(const MyStruct*s){
我的结构结果;
结果:i=s->i+1;
返回结果;
}
int32_t my_func2(){
返回42;
}
#ifdef_uucplusplus
}
#恩迪夫
lib.rs
extern crate libc;
use libc::int32_t;
#[link(name = "MyLib")]
extern {
pub fn my_func2() -> int32_t;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
unsafe {
assert_eq!(42, my_func2());
}
}
}
或者lib.rs:
extern crate libc;
use libc::int32_t;
#[repr(C)]
pub struct MyStruct {
i: int32_t
}
#[link(name = "MyLib")]
extern {
pub fn my_func(s: *mut MyStruct) -> MyStruct;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
unsafe {
let mut s = MyStruct{ i: 10 };
let s = my_func(&mut s as *mut MyStruct);
assert_eq!(11, s.i);
}
}
}
这是我收到的错误消息:
编译测试v0.1.0
错误:链接'link.exe'失败:退出代码:1120
|
//snip(但是MyLib.lib在这里)
=注:test-01aaa83d15a1dde3.0.o:错误LNK2019:函数_ZN8test5tests8it_works17h52c29448f9d86a1aE中引用的未解析外部符号my_func
C:\-01aaa83d15a1dde3.exe:致命错误LNK1120:1未解析的外部
错误:由于上一个错误而中止
错误:无法编译“测试”。
Cargo.toml
[软件包]
name=“测试”
version=“0.1.0”
作者=[“”]
[依赖关系]
libc=“0.2.17”
您是否检查了您的.lib
文件是否有任何符号/导出的函数
>dumpbin/exports/symbols MyLib.lib
Microsoft(R)COFF/PE转储程序版本14.00.24215.1
版权所有(C)微软公司。版权所有。
文件MyLib.lib的转储
文件类型:库
这意味着您的.lib
文件没有任何导出符号。您可能会想到使用\uu declspec(dllexport)
,但这似乎不适用于静态.lib
文件
Visual Studio的使用有点麻烦,但下面是如何在VS 2015中使用它的:
库MyLib
出口
my_func@1
我的_func2@2
.def
文件:
.lib
文件。如果操作正确,再次运行dumpbin
应该如下所示:
>dumpbin/exports/symbols MyLib.lib
Microsoft(R)COFF/PE转储程序版本14.00.24215.1
版权所有(C)微软公司。版权所有。
文件MyLib.lib的转储
文件类型:库
COFF符号表
000 01015E97 ABS notype Static |@comp.id
001 00000000 SECT2 notype外部| u导入u描述符MyLib
002 C0000040第2部分非类型部分| idata$2
003 00000000第3节非静态类型|.idata$6
004 C0000040未定义非类型部分|.idata$4
005 C0000040未定义非类型部分| idata$5
00600000000未定义的notype外部| u空u导入u描述符
007 00000000未定义notype外部| MyLib_NULL_THUNK_数据
字符串表大小=0x5C字节
COFF符号表
000 01015E97 ABS notype Static |@comp.id
001 00000000 SECT2 notype外部| u NULL_导入_描述符
字符串表大小=0x1D字节
COFF符号表
000 01015E97 ABS notype Static |@comp.id
001 00000000第2节非类型外部数据
字符串表大小=0x22字节
出口
序名
1我的职能
2我的职责2
总结
D2.调试$S
14.idata$2
14.idata$3
8.idata$4
8.idata$5
12.idata$6
.lib
文件(确保从正确的目录中执行此操作;请注意,64位和32位编译到不同的文件夹)复制到Rust项目的根目录:
+myrust项目/
\
+src/
+货舱
+MyLib.lib
.dll
:
.dll
复制到与.lib
相同的位置有关
.def
文件的更多信息,请参阅请提及操作系统(您似乎正在使用Windows)、Cargo.toml以及编译MyLib的方式。我似乎记得在我的VC++时代,VC++需要在导出的符号前面放置一个\uuudeclspec(dllexport)
,你能试试\uudeclspec(dllexport)
?@MatthieuM。即使是编译.lib
,也不是.dll
?。同样的问题可能不是;您是否有工具检查.lib
中包含的符号?可能还会有名称损坏/装饰。结果是没有在.lib中导出任何内容…嗯,这很痛苦。。。我希望有人能提出一个简化的方法oO@MatthieuM. 如果算上的话,我编写了一个快速python脚本来生成.def
文件,只要在我想要的每个函数之前放置一个MY_LIB_API
宏。所以我想说这是可能的,很好