我最近决定尝试使用 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 上的教程)上的许多问题,但似乎找不到解决方案。
当尝试按照 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
将这些参数放入主函数中。我也遇到了这个问题,几秒钟前我就解决了。
int main(int argv, char** args) { }
在所有 SDL 相关标头之后尝试
#undef main
。
更新。这不是一个有效的解决方案!
正如 HolyBlackCat 所指出的,这是一个相当草率的修复。 SDL 替换了 main 函数,以便执行一些否则不可能完成的初始化和/或清理,然后回调到实际的用户函数。
拦截的工作原理是将用户的主函数名称替换为
SDL_main
,并使用一个简单的宏
#define main SDL_main
用户的函数不再是应用程序的入口点,而是使用 SDL 提供的入口点。所提议的
#undef
鲁莽地禁用了拦截,人们应该认为它根本不应该起作用。对于那些在此“修复”后成功编译并运行 SDL 应用程序的人来说,这肯定只是一个依赖于平台的巧合。
OP 错误的正确解决方案是确保包含
main
的文件得到编译和链接,并且该函数具有正确的签名。正如其他人已经发布的那样。
我能想到的问题的唯一合理原因是,当您创建其中包含
main
的文件时,您忘记将其添加到构建目标中。
您应该在我的 main.cpp 所在的列表中看到 CApp.cpp。右键单击它并单击属性。单击弹出窗口中的“构建”选项卡。你应该看到这个:
单击“确定”,按 Ctrl+F11(重建)。
祝你好运。
在包含 SDL 库之前定义
SDL_MAIN_HANDLED
:
#define SDL_MAIN_HANDLED
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
最近,我遇到了这个问题,观看了一些 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; }
我仍然不清楚为什么它有效,但无论如何它有效。
这是我搜索时出现的第一个问题。 这些解决方案都不适合我。 最终我发现什么对我有用。将在这里将我的答案发布给“任何流浪者”。
我的问题是我尝试编译一些旧的 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})
知道 SDL1 已过时,您不应该使用它,但无论出于何种原因,即使您选择创建 SDL2 项目,CodeBlocks 仍会插入
#include <SDL/SDL.h>
,因此您可能需要将其更改为 #include <SDL2/SDL.h>
当我学习在 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
)