Win32 example/tutorial with GC?
Johnny
johnnykiro at gmail.com
Fri May 4 03:21:47 PDT 2007
Hello David
I didn't know how exactly to change the code in order to add the mingw32
lib (-lmingw32), so I tried a different way:
void main()
{
int
exit_code=WinMain(GetModuleHandle(null),null,GetCommandLineA(),SW_SHOWDEFAULT);
ExitProcess(exit_code);
}
extern (Windows) int WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
uint result;
result = CMDIApp.MdiWinMain(hInstance, hPrevInstance, lpCmdLine,
nCmdShow);
return result;
}
Now I have these errors:
$ ./build-gdc.sh
Compiling resources file (mdiapp.rc)..
Compiling main.d..
Linking to libraries..
main.o:main.d:(.text+0x80): undefined reference to
`_D6mdiapp7CMDIApp10MdiWinMainWT5win325winnt6HANDLET5win325winnt6HANDLEPaiZk at 16'
main.o:main.d:(.data+0x30): undefined reference to
`_D6mdiapp12__ModuleInfoZ'
collect2: ld returned 1 exit status
I'll try to figure out the reason of these errors (any hint?).
Thanks
John
David Friedman wrote:
> Johnny,
>
> I had the main/WinMain call order backwards. So, with the current
> distribution, I do not think it is possible to get the linker to
> automatically use whichever of main or WinMain is defined (like DMD
> does(?))
>
> There is a simple workaround, however: Use the following command to link.
>
> gdc -o WinMenu-gdc.exe WinMenu.d -lmingw32
>
> This will pull in MinGW's C main() that calls WinMain. The
>
> Also, you probably want to add -mwindows to the link command line so the
> .exe will not open a console when run.
>
> David
>
> Johnny wrote:
>> David,
>>
>> It's still not working with me; I must have something wrong in my code
>> or in my MinGW/GDC installation.
>>
>> Here is a simple example that I tried to compile with GDC 0.23. I
>> really wish not only to correct the problem, but to understand exactly
>> what's going wrong:
>>
>>
>> Compilation Steps:
>> -----------------
>> 1- $ gdc -c -v WinMenu.d (OK)
>>
>> Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
>> Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc
>> --disable-shared --enable-languages=c,d --host=mingw32
>> --target=mingw32 --with-gnu-ld --with-gnu-as --enable-threads
>> --disable-nls --disable-win32-registry --disable-shared
>> --enable-sjlj-exceptions
>> Thread model: win32
>> gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
>> c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d
>> -quiet -dumpbase WinMenu.d -auxbase WinMenu -version -iprefix
>> c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o
>> g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
>> GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
>> (mingw32)
>> compiled by GNU C version 3.4.2 (mingw-special).
>> GGC heuristics: --param ggc-min-expand=46 --param
>> ggc-min-heapsize=31678
>>
>> c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe
>> -o WinMenu.o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccoDaaaa.s
>>
>>
>> 2- $ gdc -v -Wall -o WinMenu-gdc.exe WinMenu.d -lgphobos (Link errors)
>>
>> Reading specs from c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
>> Configured with: ../gcc-3.4.5-20060117-1/configure --prefix=/gdc
>> --disable-shared --enable-languages=c,d --host=mingw32
>> --target=mingw32 --with-gnu-ld --with-gnu-as --enable-threads
>> --disable-nls --disable-win32-registry --disable-shared
>> --enable-sjlj-exceptions
>> Thread model: win32
>> gcc version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
>> c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/cc1d.exe WinMenu.d
>> -quiet -dumpbase WinMenu.d -auxbase WinMenu -Wall -version -iprefix
>> c:\MinGW\bin\../lib/gcc/mingw32/3.4.5/ -o
>> g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
>> GNU D version 3.4.5 (mingw special) (gdc 0.23, using dmd 1.007)
>> (mingw32)
>> compiled by GNU C version 3.4.2 (mingw-special).
>> GGC heuristics: --param ggc-min-expand=46 --param
>> ggc-min-heapsize=31678
>>
>> c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/bin/as.exe
>> -o g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o
>> g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccQJaaaa.s
>> c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic
>> -o WinMenu-gdc.exe /mingw/lib/crt2.o
>> c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o
>> -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5 -Lc:/MinGW/bin/../lib/gcc
>> -L/gdc/lib/gcc/mingw32/3.4.5
>> -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib
>> -L/mingw/lib -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../..
>> -L/gdc/lib/gcc/mingw32/3.4.5/../../..
>> g:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccwjbaaa.o -lgphobos -lgphobos
>> -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32
>> -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt
>> c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtend.o
>> /mingw/lib/libgphobos.a(cmain.o):(.text+0x19): undefined reference
>> to `_Dmain'
>> collect2: ld returned 1 exit status
>>
>>
>> It seems that the Phobos library itself refers to _Dmain and linker
>> can't find it, so where is _Dmain, and why isn't it found?
>>
>>
>> The source code file is attached.
>>
>> Thanks
>> john
>>
>>
>>
>> David Friedman wrote:
>>> Johnny wrote:
>>>> Hello
>>>>
>>>> I'm trying to make a simple windows GUI application using D.
>>>> First, I used DMD, and I suffered a lot due to it's OMF format. So I
>>>> decided
>>>> to switch to GDC (with MinGW). But I still receive linking errors
>>>> related to
>>>> Phobos :-(
>>>>
>>>> Are there any examples or tutorials that can help in this area? I.e.
>>>> ones
>>>> that show how to set the GC correctly... There are such examples for
>>>> DMD,
>>>> but I couldn't find similar examples for GDC... So any help?
>>>>
>>>> Thanks
>>>> john
>>>>
>>>>
>>>>
>>>
>>> If you are linking with other libraries, you may need to explicitly
>>> link against -lgphobos with that library early on the command line:
>>>
>>> gdc a.o b.o -lgphobos -lwsock32
>>>
>>> If you do not need a custom WinMain, just write the normal D main().
>>> Otherwise, the easiest thing to do is call _d_run_Dmain:
>>>
>>> ---
>>> import std.c.windows.windows;
>>> extern (C) int _d_run_Dmain(int argc, char **argv);
>>> extern (Windows)
>>> int WinMain(HINSTANCE hInstance,
>>> HINSTANCE hPrevInstance,
>>> LPSTR lpCmdLine,
>>> int nCmdShow)
>>> {
>>> char * fake_argv ="x";
>>> return _d_run_Dmain(1, & fake_argv);
>>> }
>>>
>>> int main(char[][] args) {
>>> return 0;
>>> }
>>> ---
>>>
>>> David
>>
>>
>> ------------------------------------------------------------------------
>>
>> import std.c.windows.windows;
>> import std.c.stdio;
>> import std.string;
>>
>> char[] Test_string="You selected Test menu item";
>> char[] Hello_string="Hello, my friend";
>> char[] Goodbye_string="See you again, bye";
>>
>> HINSTANCE hInstance;
>>
>> enum {
>> IDM_TEST=1,
>> IDM_HELLO,
>> IDM_GOODBYE,
>> IDM_EXIT
>> }
>>
>>
>> int doit() {
>> hInstance = GetModuleHandleA(null);
>>
>> WNDCLASS wc;
>>
>> wc.lpszClassName = "DWndClass";
>> wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
>> wc.lpfnWndProc = &WndProc;
>> wc.hInstance = hInstance;
>> wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION);
>> wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS);
>> wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1);
>> wc.lpszMenuName = "TestMenu";
>> wc.cbClsExtra = wc.cbWndExtra = 0;
>> RegisterClassA(&wc);
>>
>> HWND hWnd;
>> char[] sClass="My class 0";
>> char[] sApp="My Application 0";
>>
>> /+++++
>> hWnd = CreateWindowA("DWndClass", "Just a window", WS_THICKFRAME |
>> WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE,
>> CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP,
>> cast(HMENU) null, hInstance, null);
>> +++++/
>>
>> hWnd = CreateWindowA(toStringz(sClass), toStringz(sApp),
>> WS_THICKFRAME |
>> WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE,
>> CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP,
>> cast(HMENU) null, hInstance, null);
>>
>> assert(hWnd);
>>
>> ShowWindow(hWnd,SW_SHOWNORMAL);
>> UpdateWindow(hWnd);
>>
>> MSG msg;
>> while (GetMessageA(&msg, cast(HWND) null, 0, 0))
>> {
>> TranslateMessage(&msg);
>> DispatchMessageA(&msg);
>> }
>>
>> return 1;
>> }//doit()
>>
>>
>> /**********************************************************/
>>
>> /* Note the similarity of this code to the console D startup
>> * code in \dmd\src\phobos\dmain2.d
>> * You'll also need a .def file with at least the following in it:
>> * EXETYPE NT
>> * SUBSYSTEM WINDOWS
>> */
>>
>> extern (C) void gc_init();
>> extern (C) void gc_term();
>> extern (C) void _minit();
>> extern (C) void _moduleCtor();
>> extern (C) void _moduleUnitTests();
>>
>> extern (Windows)
>> int WinMain(HINSTANCE hInstance,
>> HINSTANCE hPrevInstance,
>> LPSTR lpCmdLine,
>> int nCmdShow)
>> {
>> int result;
>>
>> // gc_init(); // initialize garbage collector
>> // _minit(); // initialize module constructor table
>>
>> /* try
>> {
>> _moduleCtor(); // call module constructors
>> _moduleUnitTests(); // run unit tests (optional)
>>
>> result = doit(); // insert user code here
>> }
>> */
>> /* catch (Object o) // catch any uncaught exceptions
>> {
>> MessageBoxA(null, cast(char *)o.toString(), "Error",
>> MB_OK | MB_ICONEXCLAMATION);
>> result = 0; // failed
>> }
>> */
>> // gc_term(); // run finalizers; terminate garbage
>> collector
>> return result;
>> }
>>
>> extern(Windows)
>> {
>> void DestroyWindow(HANDLE);
>> }
>>
>> extern(Windows)
>> int WndProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
>> {
>> switch(uMsg)
>> {
>> case WM_DESTROY:
>> PostQuitMessage(cast(int) null);
>> break;
>> case WM_COMMAND:
>> switch (LOWORD(wParam))
>> {
>> case IDM_TEST:
>> MessageBoxA(cast(HANDLE) null,"Test string","Menu
>> test",MB_OK);
>> case IDM_HELLO:
>> MessageBoxA(cast(HANDLE) null,"Hello in D","Menu
>> test",MB_OK);
>> break;
>> case IDM_GOODBYE:
>> MessageBoxA(cast(HANDLE) null,"Goodbye in D","Menu test",
>> MB_OK);
>> break;
>> default:
>> DestroyWindow(hWnd);
>> }//switch menu selection
>> break;
>> default:
>> return DefWindowProcA(hWnd,uMsg,wParam,lParam);
>> }//switch msg
>> return 0;
>> }//WndProc()
>>
More information about the D.gnu
mailing list