题 调试链接错误的最佳实践


在使用C ++构建项目时,我发现调试链接错误很棘手,尤其是在获取其他人的代码时。人们使用什么策略来调试和修复链接错误?


35
2017-08-29 18:27


起源




答案:


不确定您的专业水平是什么,但这是基础知识。

下面是来自VS 2005的链接器错误 - 是的,如果你不熟悉它,那将是一个巨大的混乱。

ByteComparator.obj : error LNK2019: unresolved external symbol "int __cdecl does_not_exist(void)" (?does_not_exist@@YAHXZ) referenced in function "void __cdecl TextScan(struct FileTextStats &,char const *,char const *,bool,bool,__int64)" (?TextScan@@YAXAAUFileTextStats@@PBD1_N2_J@Z)

有几点需要关注:

  • “ByteComparator.obj” - 查找ByteComparator.cpp文件,这是链接器问题的根源
  • “int __cdecl does_not_exist(void)” - 这是它找不到的符号,在本例中是一个名为does_not_exist()的函数

此时,在许多情况下,最快的解决方法是搜索此函数的代码库并找到实现的位置。一旦知道函数的实现位置,就必须确保将两个位置链接在一起。

如果您使用的是VS2005,则可以使用“Project Dependencies ...”右键单击菜单。如果您正在使用gcc,那么您可以在makefile中查找可执行文件生成步骤(使用一堆.o文件调用gcc)并添加缺少的.o文件。


在第二种情况下,您可能缺少“外部”依赖项,而您没有代码。 Win32库通常在您必须链接到的静态库中实现。在这种情况下,请转到 MSDN 要么 “微软谷歌” 并搜索API。在API描述的底部,给出了库名。将其添加到项目属性“Configuration Properties-> Linker-> Input-> Additional Dependencies”列表中。例如,函数timeGetTime()的函数 MSDN上的页面 告诉您在页面底部使用Winmm.lib。


22
2017-09-03 02:06



好吧,如果我找到了实现该方法的地方,并且我发现它没有任何问题,我接下来该怎么办?有没有办法获得链接的文件列表?你的答案肯定对初学者有好处,但这是链接器调试的前1个结果,并且还有其他可能的原因而不是函数名中的拼写错误。 - Tomáš Zato


C运行时库通常是最大的罪魁祸首。确保所有项目具有相同的设置,包括单线程与多线程和静态与dll。

MSDN文档很适合指出特定Win32 API调用所需的lib如果缺少它。

除此之外,它通常归结为打开详细标志并浏览输出寻找线索。


3
2017-08-29 18:43





我遇到的常见链接错误之一是函数的使用方式不同于它的定义方式。如果您看到这样的错误,您应该确保您使用的每个函数都在某个.h文件中正确声明。
您还应确保将所有相关的源文件编译到同一个lib文件中。我遇到的一个错误是当我将两组文件编译成两个独立的库时,我在库之间进行交叉调用。

你有没有想到的失败?


3
2017-08-29 18:35



这个交叉调用,它给出了什么类型的错误? - Doug