2

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.

jww
  • 97,681
  • 90
  • 411
  • 885
Hashnut
  • 367
  • 3
  • 18
  • Thanks for the reply. But my code works well when i change wmain() into main()... So I guessed it has to do with wmain(). I couldn't solve the issue with the given link. – Hashnut Sep 22 '18 at 08:30
  • 1
    Possible duplicate of [wWinmain, Unicode, and Mingw](https://stackoverflow.com/q/3571250/608639), [How do I use the wmain() entry point in Code::Blocks?](https://stackoverflow.com/q/10932473/608639), etc. – jww Sep 22 '18 at 08:32

1 Answers1

4

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331