Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio Rust代码无法链接到Windows上编译的C库,因为存在未解析的外部符号_Visual Studio_Compiler Errors_Linker_Rust_Ffi - Fatal编程技术网

Visual studio Rust代码无法链接到Windows上编译的C库,因为存在未解析的外部符号

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){ 我的结

我一直试图让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){
我的结构结果;
结果: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中使用它的:

  • 创建新的“模块定义文件”(.def)
  • 填写详情:

    库MyLib
    出口
    my_func@1
    我的_func2@2
    
  • 右键单击项目,单击属性,并确保项目的配置正确:

  • 在Library下,确保设置了
    .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
    相同的位置

  • 现在,当你建立你的生锈项目,它应该工作。请注意,您必须为与Rust one相同的平台构建VS项目,因此,在我的例子中,这意味着x64,而不是x86


    有关
    .def
    文件的更多信息,请参阅请提及操作系统(您似乎正在使用Windows)、Cargo.toml以及编译
    MyLib的方式。我似乎记得在我的VC++时代,VC++需要在导出的符号前面放置一个
    \uuudeclspec(dllexport)
    ,你能试试
    \uudeclspec(dllexport)
    ?@MatthieuM。即使是编译
    .lib
    ,也不是
    .dll
    ?。同样的问题可能不是;您是否有工具检查
    .lib
    中包含的符号?可能还会有名称损坏/装饰。结果是没有在.lib中导出任何内容…嗯,这很痛苦。。。我希望有人能提出一个简化的方法oO@MatthieuM. 如果算上的话,我编写了一个快速python脚本来生成
    .def
    文件,只要在我想要的每个函数之前放置一个
    MY_LIB_API
    宏。所以我想说这是可能的,很好