【问题标题】:Why does the compiler throw "undefined reference to ..." despite providing all needed libraries in the arguments尽管在参数中提供了所有需要的库,为什么编译器会抛出“未定义的引用 ...”
【发布时间】:2019-08-03 13:23:18
【问题描述】:

我正在开发一个程序,该程序将监控所选程序的使用情况并将其记录到 .csv 文件中。这样,当我全屏运行游戏时,我可以确定哪些程序占用了特定资源的最多。我已经像这样包含了 psapi 标头:

...
#include <psapi.h>
...

我使用 MinGW 的 G++ 编译,并为我正在使用的函数提供以下选项和必要的库(库来自函数的文档):g++ -lkernel32 -lpsapi test.cpp -o test.exe

但它仍然抛出错误:

c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\james\AppData\Local\Temp\cclpYDm2.o:test.cpp:(.text+0x3e7): undefined reference to `GetProcessMemoryInfo@12'
collect2.exe: error: ld returned 1 exit status

我觉得要么是我的图书馆出了问题,要么是我做错了什么。我试过用“extern“C””包围标题,但我仍然得到相同的确切消息。我还验证了该库是否存在;如果没有,编译器会抛出一个不同的错误。 #pragma comment 也不起作用,使用 -static 标志无效。我还尝试定义 PSAPI_VERSION 宏并将其设置为 1,将其放在 psapi 的 include 语句之前。

TL;DR:尽管有正确的库,编译器仍会引发未定义的引用错误。我怀疑是:

  • 库安装不正确
  • 我在链接时出错了

【问题讨论】:

  • 对于将其标记为重复的人,您能告诉我这与什么答案有关吗?谢谢。
  • 尝试链接kernel32.lib
  • 谢谢,但不幸的是,无论是否包含 psapi 的库,它仍然抛出相同的错误。
  • @Jamesthe1 好吧,您似乎错过了链接包含GetProcessMemoryInfo() 实现的库(我猜这是Windows SDK 的一部分)。很明显,是我将其标记为重复 BTW。
  • @πάνταῥεῖ 你能重新打开这个问题吗?您链接到的高度通用的帖子中没有解决方案,我已经描述了它的不同之处。

标签: c++ g++ mingw linker-errors psapi


【解决方案1】:

请改用这个。您提供给 g++ 的参数序列实际上很重要。始终将库放在参数的末尾。

g++ -o test.exe test.cpp -lkernel32 -lpsapi

g++ 工具链首先会经过test.cpp 编译成二进制目标文件,这是一个临时文件,名字很有趣,但我们暂时称它为test.o。此时test.o中仍有部分函数引用无法解析。

然后,g++ 工具链看到-lkernel32,然后看到-lpsapi。它依次进入这两个库中,并在test.o 中为您找到那些缺少的函数。

如果是静态链接,它会从库中复制需要的函数编译后的二进制代码并拼接到test.o。如果您是动态链接,它将为动态库设置一些“入口”。

这就是顺序很重要的原因。编译器工具链将复制(设置条目)那些需要的函数,因为库通常非常大并且包含许多您并不真正需要的其他函数。当目前不需要库中的任何内容时,例如您最初编写的命令,g++ 在遇到test.cpp 之前不需要来自-lkernel32 -lpsapi 的任何内容,它只会跳过那些库。

简而言之,如果lib_a 依赖于lib_b,则应在参数中将lib_a 放在lib_b 之前。在极少数情况下,lib_x 依赖于 lib_y,而 lib_x 又依赖于 lib_x,您必须编写类似 g++ file.cpp lib_x lib_y lib_x 的内容。

请注意,此规则仅适用于库。源文件中的所有函数将保存在二进制目标文件中。因此,即使file_x 依赖于file_y,写g++ file_y.cpp file_x.cpp 也是可以的,因为所有函数都保存在file_y.ofile_x.o 中,当将它们链接在一起时,链接器可以找到它们。

相关问题:GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'

【讨论】:

  • @M.M 这是一个很好的观点。只有图书馆很重要。让我详细说明答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
  • 2014-07-30
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
相关资源
最近更新 更多