winapiunicodemingwundefined-reference

MinGW and wmain: undefined reference to `WinMain@16'


This is revisiting an issue that I thought I had already addressed, but apparently not.

I use MinGW toolchain, typically the TDM variant, to avoid issues with unavailable libraries.

I'm converting some of my Windows programs to Unicode, to provide support for Unicode filenames. However, I repeatedly have issues with the declaration of main(); when I change it to wmain(), the file compiles with no issues, but I get a linker error:

c:\tdm32\bin\g++ -Wall -s -O3 -c -Weffc++ -Wno-write-strings -DUNICODE -D_UNICODE media_list.cpp
c:\tdm32\bin\g++  media_list.o common.o qualify.o ext_lookup.o file_fmts.o conio_min.o  MediaInfoDll.o  -s -O3 -dUNICODE -d_UNICODE -o
MediaList.exe -lshlwapi
c:/tdm32/bin/../lib/gcc/mingw32/10.3.0/../../../../mingw32/bin/ld.exe: c:/tdm32/bin/../lib/gcc/mingw32/10.3.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
make: *** [MediaList.exe] Error 1

When I previously attempted to address this issue, I was using the 64-bit TDM MinGW toolchain, and I was able to resolve this issue by using the -municode linker option. However, now I am converting another console application, and am using the 32-bit TDM (g++ V10.3.0), because I'm using an addon DLL that does not support 64-bit... Unfortunately, that -municode linker option is not supported in this toolchain.

Is there some other way to resolve this issue??


Solution

  • I found the solution to this issue on Github;
    This short, simple code fragment solved the problem completely:

    //*********************************************************************
    //  this solution is from:
    //  https://github.com/coderforlife/mingw-unicode-main/
    //*********************************************************************
    #if defined(__GNUC__) && defined(_UNICODE)
    
    #ifndef __MSVCRT__
    #error Unicode main function requires linking to MSVCRT
    #endif
    
    #include <wchar.h>
    #include <stdlib.h>
    
    extern int _CRT_glob;
    extern 
    #ifdef __cplusplus
    "C" 
    #endif
    void __wgetmainargs(int*,wchar_t***,wchar_t***,int,int*);
    
    #ifdef MAIN_USE_ENVP
    int wmain(int argc, wchar_t *argv[], wchar_t *envp[]);
    #else
    int wmain(int argc, wchar_t *argv[]);
    #endif
    
    int main() 
    {
       wchar_t **enpv, **argv;
       int argc, si = 0;
       __wgetmainargs(&argc, &argv, &enpv, _CRT_glob, &si); // this also creates the global variable __wargv
    #ifdef MAIN_USE_ENVP
       return wmain(argc, argv, enpv);
    #else
       return wmain(argc, argv);
    #endif
    }
    
    #endif //defined(__GNUC__) && defined(_UNICODE)
    
    //************************************************************************
    int wmain(int argc, wchar_t *argv[])