C++ 静态库中未解析的外部符号

问题描述 投票:0回答:1

我有两个项目;静态库和测试。

我确信我已正确配置 Visual Studio 来“测试”项目使用静态库。这是我所做的:

  1. 配置库项目构建为静态库.lib
  2. 在测试中添加了附加包含目录(C/C++ -> 常规 -> 附加包含目录)
  3. 在测试中添加了附加库目录(链接器 -> 常规 -> 附加库目录)
  4. 将我的库添加为依赖项(链接器 -> 输入 -> 附加依赖项)

我可以看到我的“测试”项目看到了 .lib 文件,并且似乎“尝试”链接到它。我注意到,当我在测试项目中使用对象(在类中定义)时,一切都很好。问题是当我尝试使用函数(不是成员函数!)时。

示例:

在我的头文件(.h)中:

/*includes omitted*/

namespace kx
{
   void func();
   /*...and more API functions*/
}

在我的源文件(.cpp)中

#include "../MyHeader.h"

namespace kx
{
    void func()
    {
        /*definition...*/
    }

    /*and more definitions...*/
}

会导致链接器错误;

unresolved external symbol "void __cdecl kx::func()"

我在某处读到这是由 C 与 C++ 代码混合引起的,解决方案是在函数声明中使用

extern "C"
。我尝试过,它解决了我的问题,但我似乎不清楚,因为我只使用c++。

此外,如果我对机制的理解正确,当我使用

extern "C"
时,我的命名空间将被忽略,这正是我在这个设计中不想要的。

接下来,我认为可能是

__cdecl
导致了这个问题,所以我将函数声明更改为
void __stdcall func()
,但我有完全相同的链接器错误
unresolved external symbol "void __cdecl kx::func()"

我是一名 C++ 程序员,当我向高级人员询问我的问题时,他们告诉我,上述设计应该可以工作,无需

extern C
,除非我不将其与 C 代码混合。

我想知道我的设置/方法/设计是否有问题。最后我可以接受

extern C
的方法,但如果这是唯一的解决方案,我会感到非常惊讶。

我使用 Visual Studio 2017。

c++ static-libraries
1个回答
0
投票

正确解决此问题的方法是使用

dumpbin /SYMBOLS
检查库中的符号,并使用
link /VERBOSE

检查链接器的搜索路径

它将向您显示哪些符号可用,以及链接器在哪里寻找它们。

可能的原因是库的调用约定是

stdcall
,测试代码的调用约定是
cdecl
。 链接器正在寻找
cdecl
,但您将声明更改为
stdcall
。 您需要确保所有参考文献都是
cdecl
(或
stdcall
)才能解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.