LNK2019 - 无法解析的外部符号 - C++ - SDL2库

3

我正在尝试初始化我的游戏窗口,但卡在了这个错误上。我已经尝试过:

  • 仔细检查所有代码是否存在语法错误
  • 确认SDL2库已正确包含在我的项目中

请参考下面的代码:

头文件:

#ifndef Game_hpp
#define Game_hpp
#include "SDL.h"
#include <iostream>

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

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

    bool running()
    {
        return isRunning;
    }

private:
    bool isRunning;
    SDL_Window *window;
    SDL_Renderer *renderer;
};

#endif /* Game_hpp */

Game.cpp - 函数定义所在的地方

 #include "Game.h"

Game::Game()
{}

Game::~Game()
{}

void Game::init(const char *title, int xpos, int ypos, int width, int height, bool fullscreen)
{
    int flags = 0;
    if (fullscreen)
    {
        flags = SDL_WINDOW_FULLSCREEN;
    }

    if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "Subsystems Initialised..." << std::endl;

        window = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
        if (window)
        {   
            std::cout << "Window Created" << std::endl;
        }

        renderer = SDL_CreateRenderer(window, -1, 0);
        if (renderer)
        {
            SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
            std::cout << "Renderer Created" << std::endl;
        }

        isRunning = true;
    }

    else
    {
        isRunning = false;
    }
}

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

        default:
            break;
    }
}

void Game::update()
{}

void Game::render()
{
    SDL_RenderClear(renderer);
    //this is where we add stuff to render
    SDL_RenderPresent(renderer);
}

void Game::clean()
{
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();
    std::cout << "Game Cleaned." << std::endl;
}

主要功能:

#include "Game.h"

Game *game = nullptr;

int main(int argc, const char * argv[])
{
    game = new Game();

    game->init("BirchEngine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);

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

    game->clean();

    return 0;
}

我得到的错误:
1>SDL2main.lib(SDL_windows_main.obj):错误 LNK2019: 无法解析的外部符号 SDL_main,该符号在 main_utf8 函数中被引用
1>C:\Dev\2D_GameEngine\x64\Debug\2D_GameEngine.exe:致命错误 LNK1120: 1 个无法解析的外部
非常感谢您的帮助!

1
你已经正确地包含了SDL头文件(包含文件),但是没有在链接器设置中包含SDL库。 - Mark Setchell
1
“链接器-->常规-->附加库目录”和“链接器-->输入-->附加依赖项”可能是您要放置“SDL_main.lib”的地方。 - Arnav Borborah
1
这个问题在FAQ中有解答。Benjamin Lindley提供的方法也可以解决,但你会失去SDL2main为你做的事情(与GUI和控制台模式的兼容性,自动将命令行参数转换为UTF8)。 - keltar
如果Benjamin Lindley的答案解决了你的问题,你应该按下左边的绿色勾选标记“接受”它,并可能点赞。在问题或标题中添加任何形式的“已解决!”标记通常是不被推崇的。 - HolyBlackCat
编译器是否知道 SDL 库的位置? - Onur Tuna
显示剩余2条评论
1个回答

16

SDL(不幸的是,在我看来)做了一件奇怪的事情,他们重新定义main,以抽象应用程序入口的平台特定细节。为了避免使用此功能,请执行以下操作。在包括SDL.h之前,先定义SDL_MAIN_HANDLED

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>

这会抑制对main的重新定义。然后,在main中,在使用SDL进行其他任何操作之前,请调用此函数。

SDL_SetMainReady();

这将执行SDL所需的任何初始化(目前除了将名为SDL_MainIsReady的全局变量设置为true之外,不会执行其他操作)。


非常感谢Bejamin Lindley,问题已解决 :) - Andrei
这对我来说看起来不太对。SDL_SetMainReady()在任何平台上都不会进行任何初始化,它做的是另一件事情。引用SDL文档中的话:“这是由真正的SDL主函数调用的,以让库的其余部分知道初始化已经正确完成。如果你不知道自己在做什么就调用它,可能会导致应用程序崩溃和难以诊断的问题。”请检查主帖下keltar的评论。 - HolyBlackCat
@Andrei 我建议你寻找更好的解决方案。不仅它存在一些缺点,正如在你的问题评论中提到的那样,而且它可能无法与其他版本的SDL或其他平台兼容。 - HolyBlackCat
1
@HolyBlackCat:在调用SDL_SetMainReady之前,SDL进行的初始化与SDL无关。它只是做一些旨在使每个平台上的主要函数看起来相同的事情。如果您除了在SDL中编程外永远不会做其他事情,那么可以使用它们的主函数。但我建议不要这样做,并且认为第三方库重新定义语言标准的符号是可怕的做法。如果我正在使用两个决定这样做的不同库怎么办?幸运的是,Sam Lantinga为您提供了一种轻松退出此功能的方法。 - Benjamin Lindley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接