【问题标题】:c++ visual studio, unresolved external symbol using .lib file [duplicate]c ++ Visual Studio,使用.lib文件未解析的外部符号[重复]
【发布时间】:2017-07-19 22:04:49
【问题描述】:

我继承了一个遗留项目,该项目利用 *.lib 中的一些外部函数。据我所知,使用 *.lib 的语法是正确的,这 可以在他们使用的任何视觉工作室版本中构建。 (即有一个extern "C" 原型文件,并且所有的函数签名都是正确的)。

在构建时,我收到“错误 LNK2019:未解析的外部符号 _A86_ReadConfigReg@12 在函数中引用...”

我很确定这与 *.lib 文件有关,因为 *.lib 文件的名称中有“A86”...还有一个同名的 *.dll。

我去了项目属性 -> 链接器 -> 输入并在“附加依赖项”中列出了 *.lib 文件名,但没有运气。我尝试添加包含目录,将 *.lib 和 *.dll 复制到可执行位置。但没有运气。

我该如何解决这个错误?

【问题讨论】:

    标签: c++ visual-studio linker shared-libraries


    【解决方案1】:

    您应该做的第一件事是检查库以确保引用的函数在那里。启动 msvc 开发人员命令提示符,然后运行 ​​dumpbin.exe

    语法:

    dumpbin /exports <full path library name>
    

    这将为您提供从库中导出的所有符号的列表。

    您将从那里更清楚地知道该做什么。

    [编辑]

    dumpbin 告诉您,您的 lib 导出了一个名为 A86_ReadConfigReg 的函数,这是一个 __cdecl 签名,而不是您的链接器期望的 _A86_ReadConfigReg@12 之类的 __stdcall 签名...。您应该按顺序做/检查至少两件事的优先级。

    1. 您的链接器正在寻找帕斯卡调用签名,这很奇怪。您的项目是否将 __stdcall 作为函数调用的默认值?这由Project Properties-&gt;C/C++-&gt;Advanced-&gt;Calling Convention 中的/Gz 开关控制。默认应设置为 __cdecl (/Gd)

    2. 您应该检查您的包含文件是否将所有函数声明包含在 extern "C" { } 块中。如果他们不这样做,您可以将块放在#include 指令周围,这样您就不必修改库的文件。

    像这样:

    extern "C" {
    #include <mylib.h>
    }
    

    【讨论】:

    • 我确实这样做了,转储箱的输出有一行显示:“15 A86_ReadConfigReg”。下一步是什么?
    • @user2913869 检查链接器问题的更新答案。
    • 调用约定确实设置为 __cdecl (/Gd)。就像我在原始问题中提到的那样,头文件确实有“extern“C”{}和括号之间列出的所有函数原型。我确实看到原型是这样定义的: int _stdcall A86_ReadConfigReg (int iHandle, DWORD dwOffset, DWORD* pdwResult); 所以我也尝试将“_stdcall”标签更改为“__cdecl”,然后将其完全删除,但仍然无法构建。
    • 嗯,这不正常。看起来您的标题与库中的内容不匹配。缺少的前导 _ 和 @12 非常强烈地表明 RegConfigReg 是使用 __cdecl 编译的,但标头使用显式 __stdcall 定义了函数。几乎可以肯定,这些头文件不是用于编译这个库的头文件。除非……那个库是用 PASCAL 写的吗?
    • 不幸的是,库文件是由第 3 方提供的,所以我无法了解它们是如何生成的。我可以四处寻找相同库文件的不同版本。在这一点上可以做些什么来让它发挥作用吗?我还有一个文件名完全相同的 *.dll。我是否可能需要使用 *.dll 而不是 *.lib?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    相关资源
    最近更新 更多