[SDL2.x] WinMain vs. main

I did the following to cross-platform a program.
Does SDL2 provide something more elegant?

#if defined(_WIN64)
int WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) 
int main(int argc, char *argv[])

I tried the following, but it doesn’t work.

#include <SDL2/SDL_main.h>
int SDL_main(int argc, char *argv[])

In SDL2, just include SDL.h like normal and do:

int main(int argc, char *argv[]) // make sure you define main with the argc and argv parameters
    return 0; // make sure you have a return statement at the end

On Windows make sure you link the SDL2_main library. (This is not necessary in SDL3)

From the Windows FAQ:

[…] You should be using main() instead of WinMain() even though you are creating a Windows application, because SDL provides a version of !WinMain() which performs some SDL initialization before calling your main code. […] Under Visual C++, you need to link with SDL2main.lib. Under the gcc build environments including Dev-C++, you need to link with the output of “sdl2-config --libs”, which is usually: -lmingw32 -lSDL2main -lSDL2. […]

Your main function should be called just main, not SDL_main.

In SDL3, the include must be SDL3/SDL_main.h, not SDL2/SDL_main.h, of course

In SDL2 you need to link a static SDL2_main lib, and potentially (esp. on Windows + MinGW) some system libs, in the right order.
In SDL3 it’s (way) more elegant, there you only need to #include <SDL3/SDL_main.h> in the source file that implements your int main(int argc, char** argv) function.

1 Like

I know that it is very easy with SDL3.
I wanted to know if it was easier with SDL2 than using the #if defined(_WIN64) instructions.

I compile everything from Linux. For Windows I use the cross compiler.


gcc main.c -o main -lSDL2


x86_64-w64-mingw32-gcc main.c -o main.exe -lSDL2 -I/usr/local/include -L/usr/local/bin

We could probably help you better if you told us what exactly is going wrong when using SDL2 :wink:

your mingw command is at least missing -lSDL2_main

but to actually work with SDL2_main, IIRC the mingw commandline must have this at the the end:
-lmingw32 -lSDL2main -lSDL2 -mwindows
It’s important that this comes after your source file(s) (or your object files if you don’t do compiling and linking in one step), and IIRC it’s important that -lmingw32 comes before -lSDL2main and that -lSDL2main is before -lSDL2.

Yes, it fucking sucks - this was the main inspiration for header-only main in SDL3 :slight_smile:

1 Like

I’m missing the SDL2main.DLL, which apparently didn’t build it for me.
The Linux SDL2main is available, but it doesn’t work for Windows.

SDL2_main is not a .dll, it’s a static library (.lib or .a)

silly sidenote on translation, in German

Ja, es ist verdammt scheiße

Haha, was für ne schlechte Übersetzung, “Ja, es ist ist eine verfickte Scheiße” wär näher dran :-p

1 Like

I found such a *.a in my win64_build directory. I first copied it into the same folder as main.c, but it wasn’t accepted. When I copied them to /usr/local/bin, where the DLLs are located, it accepted it.

Now I tried something else: I deleted /usr/local/bin/libSDL2.dll and copied libSDL2.dll.a.
If I understand it correctly, the compiler doesn’t care whether it has a *.dll.a or *.dll?
Only at runtime does it necessarily bring a DLL?

the .a should be in the same directory you specify with -L - which shouldn’t be /usr/local/bin/, but the directory the SDL development libs for the targeted platform are in.

When compiling for Windows, you can’t directly link against a DLL (like you could with a .so on Linux), there those .lib or (.dll).a files are needed to link against.
.lib (MSVC; newer MinGW also supports it) or .a (MinGW) is either a static library (like SDL2main), or a linker library (see lib (Dateierweiterung) – Wikipedia or .lib files as linker input | Microsoft Learn - both only mention .lib, but .a is just the MinGW-equivalent of .lib)

1 Like

Thanks to you, now I have learned a lot again.

1 Like