c++ - QT Creator 链接器错误 : Link2019 File Not Found

标签 c++ qt linker qt-creator header-files

我不太确定我的问题出在哪里。

我正在为一个 OpenGL 项目使用 Qt Creator,这是我第一次尝试向我的项目添加另外几个类。我添加了头文件和实现文件:terrain.h、terrain.cpp、imageloader.h 和 imageloader.cpp。

我认为我的问题在于我的 .pro 文件:

HEADERS += glwidget.h \ 
imageloader.h \
terrain.h
SOURCES += glwidget.cpp main.cpp \
imageloader.cpp \
terrain.cpp

QT += opengl
CONFIG -= app_bundle
CONFIG += console c++11
INCLUDEPATH += "../include"
INCLUDEPATH += $$PWD

RESOURCES += shaders.qrc

当我运行 qmake 时,没有错误。

然后,当我构建项目时(清理后,运行 qmake),出现以下错误:

glwidget.obj:-1: error: LNK2019: unresolved external symbol "private: static class Terrain * __cdecl GLWidget::loadTerrain(char const *,float)" (?loadTerrain@GLWidget@@CAPEAVTerrain@@PEBDM@Z) referenced in function "protected: virtual void __cdecl GLWidget::initializeGL(void)" (?initializeGL@GLWidget@@MEAAXXZ)

Qt Creator 还说:找不到文件 glwidget.obj

然而,问题似乎真的出在地形类上,或者它如何与 glwidget 交互。

当我删除所有对地形的引用时,构建工作正常。

但是,当我在 glwidget.cpp 的 initializeGL() 方法中添加以下行时,出现 LINK2019 错误:

terrain = loadTerrain("test.bmp", 20);

terrain 在 glwidget.h 中定义为 terrain.cpp 中的 Terrain 类的实例:

Terrain* terrain;

并且 loadTerrain 在 glwidget.h 中定义为:

static Terrain* loadTerrain(const char* filename, float height);

有趣的是,即使注释掉了 loadTeerain 的实现,也会出现此错误。

以下是我尝试过的其他一些方法:

当我在 qmake 之前或之后运行 clean,或者删除构建文件夹中的 .obj 文件时,没有任何变化。我注意到重建项目时确实出现了 glwidget.obj 和 terrain.obj。

感谢任何帮助。如果您想查看我的任何文件,请告诉我。

编辑:即使在使 loadTerrain() 方法成为非静态方法后问题仍然存在。

EDIT 2 我似乎也忘记了它抛出的第二个错误,尽管我不确定这是否会有更多帮助:

debug\program2.exe:-1: error: LNK1120: 1 unresolved externals

debug 是 .obj 出现的文件夹,program2 是项目的名称。


已修复!事实证明,将方法设为静态是问题所在。你不能在头文件中声明一个静态方法,而这些方法将以我正在做的方式被多个源使用。我替换了:

static Terrain* loadTerrain(const char* filename, float height);

Terrain* GLWidget::loadTerrain(const char* filename, float height);

以及更改对该方法的后续调用。

感谢您的帮助!

最佳答案

通过使函数static,你给了它内部链接。这意味着您的函数的定义只能在定义它的翻译单元中找到(即 terrain.cpp),而不是 main.cpp。删除静态关键字。

这很容易用 objdump 确认。假设你有 test.h:

#ifndef _TEST_H
#define _TEST_H

static void a_func();

#endif

test.cpp:

#include "test.h"

void a_func()
{
}

main.cpp:

#include "test.h"

void a_func()
{
}

int main()
{
}

您会注意到您不会收到函数重定义错误。我们可以分别编译每个文件来检查对象:

g++ -c test.cpp -o test.o 
g++ -c main.cpp -o main.o

两者都会显示a_func:

Disassembly of section .text:

0000000000000000 <_ZL6a_funcv>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   90                      nop
   5:   5d                      pop    %rbp
   6:   c3                      retq

那么最终的二进制文件呢?

g++ main.o test.o

objdump -d ./a.out

00000000004005b6 <_ZL6a_funcv>:
  4005b6:   55                      push   %rbp
  4005b7:   48 89 e5                mov    %rsp,%rbp
  4005ba:   90                      nop
  4005bb:   5d                      pop    %rbp
  4005bc:   c3                      retq   

00000000004005bd <main>:
  4005bd:   55                      push   %rbp
  4005be:   48 89 e5                mov    %rsp,%rbp
  4005c1:   b8 00 00 00 00          mov    $0x0,%eax
  4005c6:   5d                      pop    %rbp
  4005c7:   c3                      retq   

00000000004005c8 <_ZL6a_funcv>:
  4005c8:   55                      push   %rbp
  4005c9:   48 89 e5                mov    %rsp,%rbp
  4005cc:   90                      nop
  4005cd:   5d                      pop    %rbp
  4005ce:   c3                      retq   
  4005cf:   90                      nop

它出现了两次!这就是为什么您不在要在多个翻译单元之间共享的头文件中将函数设为静态。

关于c++ - QT Creator 链接器错误 : Link2019 File Not Found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36881168/

相关文章:

macos - 将 OpenCV(带 Cuda)与实现 CUDA 函数的 C++ 代码链接起来会返回链接错误

visual-studio-2010 - OpenCV链接问题

c++ - 在 C++ <process.h> 中的头文件的 cpp 文件中启动一个线程

c++ - 从静态变量的析构函数调用的 Windows 7 上的 std::condition_variable notify() 问题

c++ - 包含 FreeRTOS 时,手动 CubeMX C 到 C++ 项目的转换失败

file - 检查文件是否等于其他

linux - Beaglebone Black 上的 Qserialport

c++ - C header 的重复符号问题

c++ - if 在 while 循环内造成麻烦

qt - 在 QML 中绘制弧/圆扇区?