Abstractioning away main/winMain

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 4 22:52:24 PDT 2015


On Saturday 05 September 2015 03:43, Prudence wrote:

> Standard and Win32 apps are so old school!
> 
> I'd like to hide WinMain by wrapping it in an application
> class(more or less).
> 
> Essentially I have an Application class
> 
> class Application
> {
>     public static Application New(void delegate() entry)
>     {
> 
>     }
> }
> 
> 
> .... Another module
> 
> extern (Windows) int WinMain(...)
> {
> 
> 
> }
> 
> .... User Module:
> 
> 
> const MyApp = Application.New({ std.stdio.writeln("MY APP IS
> COOL"); });
> 
> 
> But the lamba runs into a problem because of the static nature of
> the program... much less figuring out how to hook WinMain up into
> it.

Please provide self-contained code. Without key details it's hard to 
understand where things are going wrong.

I'm guessing your actual code essentially tries to do this:

----
class Application
{
    void delegate() entry;
    public static Application New(void delegate() entry)
    {
        auto a = new Application;
        a.entry = entry;
        return a;
    }
}

const MyApp = Application.New({import std.stdio; std.stdio.writeln("MY APP 
IS COOL"); });
    /* Error: non-constant nested delegate literal expression __lambda6 */

void main() /* or WinMain */
{
    MyApp.entry();
}
----

This doesn't work because delegates and static initialization don't go 
together. You can use a static constructor:

----
const Application MyApp;
static this()
{
    Application.New({import std.stdio; std.stdio.writeln("MY APP IS COOL"); 
});
}
----

Or you can make `entry` a function instead of a delegate:

----
class Application
{
    void function() entry;
    public static Application New(void function() entry)
    {
        ...
    }
}
----

> Essentially I don't want the user ever to have to know how there
> entry point came into being but there is this funkyness about it
> because Application never gets any control to call the user's
> Entry function. Whats worse is that D tries to evaluate the
> lambda at compile time. It's as if D only allows non-static data
> inside functions.
> 
> 
> The idea is to have WinMain actually call the Entry lamba
> function once it gets ran(transfer control)... but this seems to
> be difficult or impossible with D and I'm not sure why or, if
> not, how to get it to work without having to make the user jump
> through hoops.
> 
> I suppose I could create the Application(Using New instead of
> new) inside of WinMain, but the issue still remains on how to get
> the user entry point(I suppose some compile time reflection could
> be used?).
> 
> Any ideas?

I'm probably being naive and the following falls short somehow, but how 
about this:

----
/* your module */
void function() userMain;

void main() /* or WinMain */
{
    /* ... stuff ... */
    userMain();
    /* ... stuff ... */
}

/* user module: */
/* import your module; */
static this()
{
    userMain = {import std.stdio; std.stdio.writeln("MY APP IS COOL"); };
}
----


More information about the Digitalmars-d-learn mailing list