Thread overview
Operaror 'new' inside WinMain crashes at runtime
Aug 09, 2006
Serg Kovrov
Aug 09, 2006
Serg Kovrov
Aug 09, 2006
Derek Parnell
Aug 10, 2006
Serg Kovrov
Aug 10, 2006
Derek Parnell
Aug 10, 2006
Sean Kelly
Aug 11, 2006
Bruno Medeiros
August 09, 2006
Consider this sample:
> import std.c.windows.windows;
> 
> class Test {}
> 
> extern (Windows)
> int WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow)
> {
> 	new Test(); // <-- here
> 	return 0;
> }

When running executable got a runtime error. There is some info/dump on the error, but I can't save/copy it. This is part of it: Exception Information - code: 0xc0000005; Flags: 0x00000000; record: 0x0000000000000000; Address: 0x0000000000402be5; and some system information, followed lots of modules information...

This only occurs within WinMain program. eg console
application (with 'main()' entry) did not reproduce this error.

Compiled with: `dmd test.d gdi32.lib test.def`
test.def is standard windows def:
> EXETYPE NT
> SUBSYSTEM WINDOWS

Can anyone confirm this?

-- 
serg.
August 09, 2006
Forget to mention - DMD Compiler v0.163

-- 
serg.
August 09, 2006
On Wed, 09 Aug 2006 03:12:47 +0300, Serg Kovrov wrote:

> Consider this sample:
>> import std.c.windows.windows;
>> 
>> class Test {}
>> 
>> extern (Windows)
>> int WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow)
>> {
>> 	new Test(); // <-- here
>> 	return 0;
>> }
> 
> When running executable got a runtime error. There is some info/dump on the error, but I can't save/copy it. This is part of it: Exception Information - code: 0xc0000005; Flags: 0x00000000; record: 0x0000000000000000; Address: 0x0000000000402be5; and some system information, followed lots of modules information...
> 
> This only occurs within WinMain program. eg console
> application (with 'main()' entry) did not reproduce this error.
> 
> Compiled with: `dmd test.d gdi32.lib test.def`
> test.def is standard windows def:
>> EXETYPE NT
>> SUBSYSTEM WINDOWS
> 
> Can anyone confirm this?

Confirmed. However this is not the way to write Windows apps. You missed out all the GC stuff. The code should look like this ...

import std.c.windows.windows;

extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleDtor();
extern (C) void _moduleUnitTests();

extern (Windows)
int WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int
cmdShow)
{
    int result;

    gc_init();          // initialize garbage collector
    _minit();           // initialize module constructor table

    try
    {
        _moduleCtor();      // call module constructors
        _moduleUnitTests(); // run unit tests (optional)

        result = mymain(instance, prevInstance, cmdLine, cmdShow);

        _moduleDtor();      // call module destructors
    }

    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;
}

class Test {}
int mymain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int
cmdShow)
{
    auto x = new Test();
    return 0;
}


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
9/08/2006 10:22:22 AM
August 10, 2006
* Derek Parnell:
> Confirmed. However this is not the way to write Windows apps. You missed
> out all the GC stuff. The code should look like this ...

Thanks for pointing that, Derek. It is silly of me that I forgot about that =)

But isn't it tedious to type/copy this for every new windows program one start to write?

And appears to me, this is some inner GC stuff that might me changed at some point. If so, maybe this should not be used directly by application programmer? I believe it is better to have compiler/standard library to do it instead. Just like it does for main() function.

Even better, if application programmer do always write main(), but if in .def there is 'SUBSYSTEM WINDOWS' string, compiler/standard library substitutes it with proper entry point with proper inners stuff initialization.

Or even better than better, is to omit .def files and have some pragmas in source file instead? Resulting programs could be more portable/deployable then...
August 10, 2006
On Thu, 10 Aug 2006 11:28:08 +0300, Serg Kovrov wrote:

> But isn't it tedious to type/copy this for every new windows program one start to write?

Yes, that's why I've got that code in a module so all I have to do is ...

  import util.winstart;

Build handles the connections and .DEF file generation for me.

-- 
Derek Parnell
Melbourne, Australia
"Down with mediocrity!"
August 10, 2006
Serg Kovrov wrote:
> * Derek Parnell:
>> Confirmed. However this is not the way to write Windows apps. You missed
>> out all the GC stuff. The code should look like this ...
> 
> Thanks for pointing that, Derek. It is silly of me that I forgot about that =)
> 
> But isn't it tedious to type/copy this for every new windows program one start to write?
> 
> And appears to me, this is some inner GC stuff that might me changed at some point. If so, maybe this should not be used directly by application programmer? I believe it is better to have compiler/standard library to do it instead. Just like it does for main() function.
> 
> Even better, if application programmer do always write main(), but if in .def there is 'SUBSYSTEM WINDOWS' string, compiler/standard library substitutes it with proper entry point with proper inners stuff initialization.
> 
> Or even better than better, is to omit .def files and have some pragmas in source file instead? Resulting programs could be more portable/deployable then...

What I did for a while was to call C main from WinMain, as that's where the D startup code lives.  However, someone told me that it's possible to have C main as the entry point for a Win app so I got rid of the module that I used to use.  I don't suppose anyone can confirm this or say how to do it?  It seems it would be far cleaner than linking against a WinMain module manually, even if the administrative bits are abstracted out.


Sean
August 11, 2006
Sean Kelly wrote:
> Serg Kovrov wrote:
>> * Derek Parnell:
>>> Confirmed. However this is not the way to write Windows apps. You missed
>>> out all the GC stuff. The code should look like this ...
>>
>> Thanks for pointing that, Derek. It is silly of me that I forgot about that =)
>>
>> But isn't it tedious to type/copy this for every new windows program one start to write?
>>
>> And appears to me, this is some inner GC stuff that might me changed at some point. If so, maybe this should not be used directly by application programmer? I believe it is better to have compiler/standard library to do it instead. Just like it does for main() function.
>>
>> Even better, if application programmer do always write main(), but if in .def there is 'SUBSYSTEM WINDOWS' string, compiler/standard library substitutes it with proper entry point with proper inners stuff initialization.
>>
>> Or even better than better, is to omit .def files and have some pragmas in source file instead? Resulting programs could be more portable/deployable then...
> 
> What I did for a while was to call C main from WinMain, as that's where the D startup code lives.  However, someone told me that it's possible to have C main as the entry point for a Win app so I got rid of the module that I used to use.  I don't suppose anyone can confirm this or say how to do it?  It seems it would be far cleaner than linking against a WinMain module manually, even if the administrative bits are abstracted out.
> 
> 
> Sean

Yes, just link a C main program with a def file with:
  EXETYPE NT
  SUBSYSTEM WINDOWS
and a program without the console window will be created. That's what the dbuild option "-gui" does as well. (now that I think about it, that option seems a bit misnamed, maybe it should be "-win"? :) )

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D