The declaration of wWinMain in winbase.h looks like this:
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd);
Unfortunately the data in "lpCmdLine" is not a wide-string, but just a normal LPSTR masked behind the LPWSTR type. Visual Studio is passing it correctly as wide-string. Here's some debugger output, that confirms this issue:
Breakpoint 1, wWinMain (instance=0x400000, prev_instance=0x0,
command_line_w=0x20575 L<error reading variable>, cmd_show=10)
at src/mess/tools/imgtool/windows/wmain.c:23
23 int pos, rc = -1;
(gdb) print (char*)command_line_w
$1 = 0x20575 ""
It also appears this bug has been around for years in MinGW now, since when I fixed the code for Visual Studio to correctly handle the LPWSTR I broke the MinGW version.
Sorry I forgot to add the compiler information:
Using built-in specs.
Target: i686-w64-mingw32
Configured with: ../gcc44-svn/configure --target=i686-w64-mingw32 --host=i686-w6
4-mingw32 --disable-multilib --disable-nls --prefix=/mingw64-w32 --with-sysroot=
/mingw64-w32 --with-gmp=/mingw64-w32 --with-mpfr=/mingw64-w32 --enable-languages
=c,c++
Thread model: win32
gcc version 4.4.3 20091223 (prerelease) r155431 (GCC)
Hi,
Try rebuilding the CRT, with crt/ucrtexe.c changed to have:
#ifndef UNICODE
#define UNICODE
#define _UNICODE
#endif
Does it fix the issue?
Hmmm, I don't remember offhand if gcc 4.4 series supports the flag, but in order to get the wide versions of the startup you need to use -municode...
From the way it prints the svn rev. number, it looks like one of my builds, so it should support -municode.
The binary was built with "-DUNICODE -D_UNICODE -municode" and I have no idea and not really the time at my hands to rebuilt GCC myself.
Can you please post a test case that exhibits the issue?
kidkat: rebuild the mingw-w64-crt and see if it helps with the new changes.
sezero: its not a link time issue. I see a potential bug in crt/crtexe.c, see line 238, refer to ucrtexe.c as well, _UNICODE define is missing when TCHAR is used. I'm not too sure if this is the root of the issue.
preprocessed - compile the testcase with -save-temps and post the resulting .i file. Along with command line options used.
Thanks
Jon: that seems like a big ouch ouch ouch.. We need something like:
--- ucrtexe.c~ 2010-05-03 17:02:44.000000000 +0300
+++ ucrtexe.c 2010-05-16 20:54:59.000000000 +0300
@@ -7,6 +7,9 @@
#ifndef UNICODE
#define UNICODE
#endif
+#ifndef _UNICODE
+#define _UNICODE
+#endif
#define WPRFLAG 1
... yes? Kai? How did we miss this one for so long?
Seeing the preprocessed testcase would confirm this.
I attached a sample with preprocessed files. I compiled it using:
gcc -save-temps -mwindows -municode -DUNICODE -D_UNICODE -o wwinmain_test.exe wwinmain_test.c
It shows two messageboxes. The first one is the UNICODE one, that show garbage, since it's not a proper unicode string and the second one uses ANSI and is empty since the string is empty. (somehow I didn't manage, that wWinMain is actually getting the command-line - it works in the project I had the issue in).
source, executables and preprocessed source files
Thanks for reporting. It seems to me that the -municode application option isn't used pretty often, so we didn't notice it.
Yes, should define for the unicode-startup both. UNICODE and _UNICODE. This should fix this issue (Please don't play with crt build options here, do it just in the unicode file wrappers).
The crt files have been fixed in our svn repo, rev. 2378 for the 1.0 branch and rev. 2379 for the trunk. Please recompile the mingw-w64-crt using those changes and replace crt1u.o and crt2u.o with the new ones and see if it fixes your issues. If you can't or don't want to compile the crt by yourself, I uploaded a tiny zips files, one for the 32 bit runtime and one for the 64 bit one, here (I can't attach them here for whatever reason..) :
http://uhexen2.sf.net/tmp/32u.zip
http://uhexen2.sf.net/tmp/64u.zip
(They should be compatible with the toolchain version you told us about.) Tell us whether they fix your problems.
It seems the issue is fixed (I just tred the 32-bit version):
Breakpoint 1, wWinMain (instance=0x400000, prev_instance=0x0,
command_line_w=0x205ae L<error reading variable>, cmd_show=10)
at src/mess/tools/imgtool/windows/wmain.c:23
23 int pos, rc = -1;
(gdb) print command_line_w
$1 = (LPWSTR) 0x205ae L<error reading variable>
(gdb) print (char*)command_line_w
$2 = 0x205ae "t"
(gdb) print (wchar_t*)command_line_w
$3 = 0x205ae L<error reading variable>
(gdb) print (char*)command_line_w+1
$4 = 0x205af ""
(gdb) print (char*)command_line_w+2
$5 = 0x205b0 "e"
(gdb) print (char*)command_line_w+3
$6 = 0x205b1 ""
(gdb) print (char*)command_line_w+4
$7 = 0x205b2 "s"
(gdb) print (char*)command_line_w+5
$8 = 0x205b3 ""
(gdb) print (char*)command_line_w+6
$9 = 0x205b4 "t"
I passed "test" as parameter and it is properly encoded as a wide-string now. Thanks.
Unfortunately gdb still can't show the contents of of a wide-string. Should I file another report for that or isn't it supposed to do that?
Thanks for the feedback. I think this can be closed as fixed.
As for the gdb not being able to properly show wide-strings, that should be a problem in gdb itself and should be reported to gdb, but others here may have more to say on the matter.
IIRC, in order for gdb to be able to do wchar_t strings, you need to link with libiconv. Otherwise, it just fakes it and uses the ASCII charset...
The issues of not being able to pass the command-line to wWinMain appears to be another problem since it doesn't work in the project either. It works fine in Vsiaul Studio 2010. Opening another ticket with the same sample.
Nevermind my last comment. It is also fixed with the updated .o files you posted.