c++ - 尽管在参数中提供了所有需要的库,但为什么编译器会抛出 "undefined reference to ..."

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

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

...
#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:尽管有正确的库,编译器仍抛出 undefined reference 错误。我怀疑是:

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

最佳答案

请试试这个。您提供给 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,您必须编写类似 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()'

关于c++ - 尽管在参数中提供了所有需要的库,但为什么编译器会抛出 "undefined reference to ...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57338722/

相关文章:

c++ - 如何有条件地为 Eclipse 中的交叉编译项目包含两个相同版本的不同名称的库?

c++ - MinGW 包含路径冲突

c++ - 关联两个独立的键

c++ - 将值从一个 vector 复制到另一个 vector (来自书籍)

c++ - 从 qml 访问 QList<T>

c++ - 如何解释此错误,堆摘要,未初始化的变量?

c++ - nuwen MinGW + Boost- 错误链接 boost_regex

c++ - 并发写入 vector<bool>

在Ubuntu上编译动态链接库并获得无法识别的调试输出级别

c++ - __cplusplus 宏告诉 g++ C 头文件声明不正常工作