未定义对“SDL_main”的引用

问题描述 投票:0回答:8

我最近决定尝试使用 SDL 和 CodeBlocks 10.05。我从 http://www.sdltutorials.com/sdl-tutorial-basics 上的教程开始,并尽力遵循它。不幸的是,我遇到了:

..\..\..\..\..\..\SDL\SDL-1.2.15\lib\libSDLmain.a(SDL_win32_main.o):SDL_win32_main.c|| undefined reference to `SDL_main'|

当我尝试编译它时。

我搜索了这个网站和其他教程(主要是 LazyFoo 和 CodeBlocks wiki 上的教程)上的许多问题,但似乎找不到解决方案。

  • C:\SDL\SDL-1.2.15\include 已添加到编译器选项卡(搜索目录)
  • C:\SDL\SDL-1.2.15\lib 已添加到链接器选项卡中
  • 库 libmingw32.a、libSDLmain.a、libSDL.dll.a 按此顺序链接
    • CodeBlocks 安装目录中 MinGW\lib 文件夹中的 libmingw32.a
  • SDL.dll 位于 System32 文件夹和项目文件夹中

当尝试按照 CodeBlocks wiki 上的教程进行操作时,我被告知在给定目录中找不到 SDL.h(当创建新的 SDL 项目时)。

CApp.cpp

#include "CApp.h"
#include "SDL\SDL.h"

CApp::CApp(){
    Surf_Display=NULL;

    Running=true;
}

int CApp::OnExecute(){
    if (OnInit()==false){
        return -1;
}

SDL_Event Event;

while (Running){
    while (SDL_PollEvent(&Event)){
        OnEvent(&Event);
    }
    OnLoop();
    OnRender();
}

OnCleanup();
return 0;
}

int main(int argc, char* argv[]){
    CApp theApp;

    return theApp.OnExecute();
}

CApp.h

#ifndef CAPP_H_INCLUDED
#define CAPP_H_INCLUDED
#include "SDL\SDL.h"

class CApp{
    private:
        bool Running;
        SDL_Surface* Surf_Display;

    public:
        CApp();
        int OnExecute();

    public:
        bool OnInit();
        void OnEvent(SDL_Event* Event);
        void OnLoop();
        void OnRender();
        void OnCleanup();
};



#endif // CAPP_H_INCLUDED
c++ sdl codeblocks
8个回答
44
投票

将这些参数放入主函数中。我也遇到了这个问题,几秒钟前我就解决了。

int main(int argv, char** args) { }


17
投票

在所有 SDL 相关标头之后尝试

#undef main

更新。这不是一个有效的解决方案!

正如 HolyBlackCat 所指出的,这是一个相当草率的修复。 SDL 替换了 main 函数,以便执行一些否则不可能完成的初始化和/或清理,然后回调到实际的用户函数。

拦截的工作原理是将用户的主函数名称替换为

SDL_main
,并使用一个简单的宏

#define main SDL_main

用户的函数不再是应用程序的入口点,而是使用 SDL 提供的入口点。所提议的

#undef
鲁莽地禁用了拦截,人们应该认为它根本不应该起作用。对于那些在此“修复”后成功编译并运行 SDL 应用程序的人来说,这肯定只是一个依赖于平台的巧合。

OP 错误的正确解决方案是确保包含

main
的文件得到编译和链接,并且该函数具有正确的签名。正如其他人已经发布的那样。


8
投票

我能想到的问题的唯一合理原因是,当您创建其中包含

main
的文件时,您忘记将其添加到构建目标中。

enter image description here

您应该在我的 main.cpp 所在的列表中看到 CApp.cpp。右键单击它并单击属性。单击弹出窗口中的“构建”选项卡。你应该看到这个:

enter image description here

单击“确定”,按 Ctrl+F11(重建)。

祝你好运。


3
投票

在包含 SDL 库之前定义

SDL_MAIN_HANDLED

#define SDL_MAIN_HANDLED
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

更多信息:我正在使用 SDL 函数,但未定义 SDL_main。这样可以吗


2
投票

最近,我遇到了这个问题,观看了一些 YouTube 视频,并按照 LazyFoo 的安装指南进行操作,但我不断收到“对 SDL_main 的未定义引用”错误。

在成功将 minGw 文件链接到我的项目属性后,我遵循了这里所说的一切,但直到我添加到我的主函数中后它才起作用

int main (int argv, char** args)
瞧,它起作用了。

using namespace std;

int main(int argv, char** args) {    if(SDL_Init(SDL_INIT_VIDEO)<0)    {
       cout<<"Endl Init Failed."<<endl;
       return 1;    }

   cout<<"SDL Init succeeded."<<endl;

   SDL_Quit();    return 0; }

我仍然不清楚为什么它有效,但无论如何它有效。


0
投票

这是我搜索时出现的第一个问题。 这些解决方案都不适合我。 最终我发现什么对我有用。将在这里将我的答案发布给“任何流浪者”。

我的问题是我尝试编译一些旧的 C 游戏而不是 C++ 游戏。 对我来说解决方案的一部分是将 main.c 重命名为 main.cpp 然后向 CMake 发出信号,对所有 C 文件使用 CPP 编译器。 最终这是我的 CMakeLists.txt 的一部分:

# set minimum cmake version
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)

# project name and language
project(FootballManager LANGUAGES CXX)

# This is mandatory too, because otherwise they are not compiled an linked.
file(GLOB_RECURSE CFILES "${CMAKE_SOURCE_DIR}/*.c")
SET_SOURCE_FILES_PROPERTIES(${CFILES} PROPERTIES LANGUAGE CXX)

# list sources
list(APPEND _sources config.h)
# ... removed some of the other sources for brevity ...
list(APPEND _sources misc.c)

# Link SDL, yes this is SDL1.2
find_package(SDL REQUIRED)
include_directories(FootballManager ${SDL_INCLUDE_DIRS})

add_executable(fm main.cpp ${_sources})

target_link_libraries(fm ${SDL_LIBRARIES})

0
投票

知道 SDL1 已过时,您不应该使用它,但无论出于何种原因,即使您选择创建 SDL2 项目,CodeBlocks 仍会插入

#include <SDL/SDL.h>
,因此您可能需要将其更改为
#include <SDL2/SDL.h>


0
投票

当我学习在 Visual Studio Code(语言 C++)中使用 SDL 和 CMake 时,我遇到了这个问题。我直接在main.cpp文件中使用时,项目运行良好。但是当我定义一个类并在该类源文件中使用SDL时,出现了这个错误。对我有用的解决方案是在 main 函数之前使用 extern "C" 。我希望这个解决方案能够帮助那些走同样道路的人。

extern "C" int main(int argc, char* argv[])

主.cpp

#include "Game.hpp"

Game *game = nullptr;

extern "C" int main(int argc, char* argv[]) {

    game = new Game();

    game->init("Game Window", 100, 100, 800, 600, false);

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

    game->clean();
    delete game;

    return 0;
    
}

游戏.hpp

#pragma once

#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);
    bool running() { return isRunning; }
    void handleEvents();
    void update();
    void render();
    void clean();
private:
    bool isRunning;
    SDL_Window* window;
    SDL_Renderer* renderer;
};

CMakeLists.txt

cmake_minimum_required(VERSION 3.30.3)
project(TheWasteland VERSION 0.1.0)

# Adding all the source files in project
file(GLOB_RECURSE CPP_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")

# Adding SDL2 in project
set(SDL2_DIR "C:/SDL/SDL2/cmake") 
set(SDL2_Image_DIR "C:/SDL/SDL2_image/cmake") 
find_package(SDL2 REQUIRED)
find_package(SDL2_Image REQUIRED)

# Adding executable
add_executable(${PROJECT_NAME} ${CPP_FILES})

# Include directories
include_directories(${PROJECT_NAME}  
    ${SDL2_INCLUDE_DIRS}
    ${CMAKE_SOURCE_DIR}/src
)

# Linking the libraries used in project
target_link_libraries(${PROJECT_NAME}
    SDL2::SDL2main
    SDL2::SDL2
    SDL2_image::SDL2_image
)
© www.soinside.com 2019 - 2024. All rights reserved.