Search code examples
c++unicodemingwwmain

C++ wmain function error when using Unicode


I was trying to use wmain for simple test code to practice with WCS strings (not MBCS), but I'm consistently getting error, while can't find out why.

Here is my code.

#include <iostream>
#include <stdio.h>

using namespace std;

int wmain(int argc, wchar_t * argv[])
{
    for (int i = 1; i < argc; i++) {
        fputws(argv[i], stdout);
        fputws(L"\n", stdout);
    }

    return 0;
}

And it gives the error message.

c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16' collect2.exe: error: ld returned 1 exit status

Why does it crash? I cannot find out why this error comes up.


Solution

  • wmain is a Visual C++ language extension for handling UTF-16 encoded command line arguments in Windows.

    It is however supported by modern MinGW g++, the compiler you're using, via option -municode.

    For a compiler that doesn't support it you can easily write a few lines' standard main that calls Windows' GetCommandLineW and CommandLineToArgvW, and then calls a wmain function.


    Example of a standard main that calls wmain, as sketched above:

    #ifdef USE_STD_MAIN
    #include <stdlib.h>         // EXIT_...
    #include <windows.h>        // GetCommandLineW, CommandLineToArgvW
    #include <memory>           // std::(unique_ptr)
    auto main()
        -> int
    {
        int n_args;
        wchar_t** p_args = CommandLineToArgvW(GetCommandLineW(), &n_args );
        if( p_args == nullptr )
        {
            return EXIT_FAILURE;
        }
        const auto cleanup = []( wchar_t** p ) { LocalFree( p ); };
        try
        {
            std::unique_ptr<wchar_t*, void(*)(wchar_t**)> u( p_args, cleanup );
            return wmain( n_args, p_args );
        }
        catch( ... )
        {
            throw;
        }
    }
    #endif
    

    The purpose of the try-catch that doesn't seem to do anything, is to guarantee that calls of destructors of local variables like u here, is done for a call to wmain.

    Disclaimer: I just wrote that code. It's not been extensively tested.