C++ main.cpp:(.text+0x5f): 未定义的引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21268483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:34:50  来源:igfitidea点击:

main.cpp:(.text+0x5f): undefined reference to

c++linkerg++sdl

提问by IIanFumenchu

I try to compile some exercise from a SDL guide.

我尝试从 SDL 指南中编译一些练习。

I compile like this:

我这样编译:

g++ -o main main.cpp -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2

and i get this:

我明白了:

/tmp/cci2rYNF.o: In function `main':
main.cpp:(.text+0x5f): undefined reference to `Game::init(char const*, int, int, int, int, int)'
collect2: error: ld returned 1 exit status

and my code is:

我的代码是:

main.cpp

主程序

#include "Game.h"

// our Game object
Game* g_game = 0;

int main(int argc, char* argv[])
{
    g_game = new Game();
    g_game->init("Chapter 1", 100, 100, 640, 480, 0);

    while(g_game->running())
    {
    g_game->handleEvents();
    g_game->update();
    g_game->render();
    }
    g_game->clean();

    return 0;
}

Game.h

游戏.h

#ifndef __Game__
#define __Game__

#include <SDL.h>

class Game
{
    public:
      Game() {}
      ~Game() {}

      bool init(const char* title, int xpos, int ypos, int width, int height, int flags);
      void render(){}
      void update(){}
      void handleEvents(){}
      void clean(){}

      // a function to access the private running variable
      bool running() { return m_bRunning; }

    private:

      SDL_Window* m_pWindow;
      SDL_Renderer* m_pRenderer;
      bool m_bRunning;
};

#endif // defined(__Game__) */

Game.cpp

游戏.cpp

#include "Game.h"

bool Game::init(const char* title, int xpos, int ypos, int width, int height, int flags)
{
    // attempt to initialize SDL
    if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
    std::cout << "SDL init success\n";
    // init the window
    m_pWindow = SDL_CreateWindow(title, xpos, ypos,
    width, height, flags);

    if(m_pWindow != 0) // window init success
    {
        std::cout << "window creation success\n";
        m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
        if(m_pRenderer != 0) // renderer init success
        {
        std::cout << "renderer creation success\n";
        SDL_SetRenderDrawColor(m_pRenderer,
        255,255,255,255);
        }
        else
        {
        std::cout << "renderer init fail\n";
        return false; // renderer init fail
        }
    }
    else
    {
        std::cout << "window init fail\n";
        return false; // window init fail
    }
    }
    else
    {
    std::cout << "SDL init fail\n";
    return false; // SDL init fail
    }
    std::cout << "init success\n";
    m_bRunning = true; // everything inited successfully, start main loop

    return true;
}


void Game::render()
{
    SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
    SDL_RenderPresent(m_pRenderer); // draw to the screen
}


void Game::clean()
{
    std::cout << "cleaning game\n";
    SDL_DestroyWindow(m_pWindow);
    SDL_DestroyRenderer(m_pRenderer);
    SDL_Quit();
}

void Game::handleEvents()
{
    SDL_Event event;
    if(SDL_PollEvent(&event))
    {
      switch (event.type)
      {
        case SDL_QUIT:
          m_bRunning = false;
        break;

        default:
        break;
      }
    }
}

回答by kfsone

C and C++ have the concept of a "compilation unit", this is the source file which the compiler was invoked with and all of the code that it #includes.

C 和 C++ 有“编译单元”的概念,这是调用编译器的源文件及其所有代码#include

GCC, MSVC and most other compilers will generate an intermediate "object file" (.o or .obj) for each compilation unit. These must then be combined together, along with any libraries, to form the final executable, in a step referred to as "linking".

GCC、MSVC 和大多数其他编译器将为每个编译单元生成一个中间“目标文件”(.o 或 .obj)。然后,这些必须与任何库一起组合在一起,以形成最终的可执行文件,在一个称为“链接”的步骤中。

With GCC there are a few ways to do this. Single command:

使用 GCC,有几种方法可以做到这一点。单个命令:

g++ -o app.exe file1.cpp file2.cpp

This compiles file1.cpp and file2.cpp separately (each is still a single compilation unit) to object files and then links the resulting object files to an executable called "app.exe" (you don't need the .exe extension, I'm just using it for clarity)

这将分别将 file1.cpp 和 file2.cpp(每个仍然是一个单独的编译单元)编译为目标文件,然后将生成的目标文件链接到名为“app.exe”的可执行文件(您不需要 .exe 扩展名,我只是为了清楚起见而使用它)

Or multiple commands:

或多个命令:

g++ -o file1.o -c file1.cpp
g++ -o file2.o -c file2.cpp
g++ -o app.exe file1.o file2.o

This performs the compilation step on each cpp individually and then performs a separate link step with 'g++' acting as a front-end to each step. Note the -cin the first two lines, which tells it you want to compile C/C++ source to .object. The 3rd line, the compiler front-end recognizes you're asking it to compile object files, and figures out you want to do the link step.

这会分别在每个 cpp 上执行编译步骤,然后使用“g++”作为每个步骤的前端执行单独的链接步骤。请注意-c前两行中的 ,它告诉它您要将 C/C++ 源代码编译为 .object。第 3 行,编译器前端识别出您要求它编译目标文件,并确定您想要执行链接步骤。

The first method is often easiest for small projects, the second method is useful when you are using any kind of build system and things start to get complicated.

对于小型项目,第一种方法通常最简单,当您使用任何类型的构建系统并且事情开始变得复杂时,第二种方法很有用。

回答by John Dibling

You aren't compiling Game.cpp. Try:

你没有编译Game.cpp。尝试:

g++ -o main main.cpp Game.cpp -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2

The problem is that although you #included Game.hin main.cpp, it references functions that are defined in Game.cpp. Without compiling that as well, the linker doesn't have the definitions required to make an executable.

问题是,尽管您在 中#included ,但它引用了 中定义的函数。如果不编译它,链接器就没有生成可执行文件所需的定义。Game.hmain.cppGame.cpp