www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calling main() from WinMain()

reply "BLM768" <blm768 gmail.com> writes:
I'm working on a cross-platform GUI library and I'd like to be 
able to call the user's main() function from WinMain() so users 
don't have to write both functions. However, I'm at a bit of a 
loss as to how to accomplish that. I know that D internally 
creates the extern(C) main(), which in turn calls D's main(), but 
I think that the C main() also performs some runtime 
initialization, which means that I probably shouldn't be calling 
it after WinMain() has already started. Since the D main() is 
defined at module scope, I'm not sure how to access it without 
importing one of the user's modules. I think that each module can 
define its own main() as well, which really complicates things. 
Is there a reasonably simple way to get the right main() function?

I hate to say it, but this is a problem that would actually be 
easier in C++ :)
Jun 05 2012
next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/05/12 16:40, BLM768 wrote:
 I'm working on a cross-platform GUI library and I'd like to be able to call
the user's main() function from WinMain() so users don't have to write both
functions. However, I'm at a bit of a loss as to how to accomplish that. I know
that D internally creates the extern(C) main(), which in turn calls D's main(),
but I think that the C main() also performs some runtime initialization, which
means that I probably shouldn't be calling it after WinMain() has already
started. Since the D main() is defined at module scope, I'm not sure how to
access it without importing one of the user's modules. I think that each module
can define its own main() as well, which really complicates things. Is there a
reasonably simple way to get the right main() function?
 
 I hate to say it, but this is a problem that would actually be easier in C++ :)

D main's name is not mangled (which also causes trouble if you try to define a "main" inside more than one module). So you can just do extern (C) int _Dmain(string[] args); and call this one (assuming that Windows doesn't need special treatment, no idea about that) artur
Jun 05 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/5/12, BLM768 <blm768 gmail.com> wrote:
 I'm working on a cross-platform GUI library and I'd like to be
 able to call the user's main() function from WinMain() so users
 don't have to write both functions.

GUI libraries don't have to work this way. You could instantiate an "App" and then call some internal "run" method which starts an event loop which reacts to events retrieved from the OS, e.g. (pseudocode): class MyApp : App { this() { this.size = Size(400, 400); this.position = Point(600, 400); Widget mainWidget = new Widget(128, 128); connect(mainWidget, Event.Move, &onMove); this.addWidget(mainWidget); } void onMove(Widget src, Point loc) { } } void main(s) { auto app = new MyApp(); app.run(); } So after calling run() the GUI library keeps processing OS events until maybe the last window is closed, and then other statements are executed in main. You don't really need a WinMain() function to call OS GUI functions like GDI. For Windows you need to register a WNDCLASS and a WndProc (a dispatch function which processes OS events), create a window and then use an event loop like "while (GetMessage(&msg, NULL, 0, 0))".
Jun 05 2012
prev sibling next sibling parent "BLM768" <blm768 gmail.com> writes:
I've researched this some more, and it appears that WinMain() 
actually doesn't do any runtime initialization. That means I 
should be able to just call the C main from WinMain() and let it 
initialize the runtime and call _Dmain(). The main problem I have 
now is that as soon as I put main() in, DMD uses it as the entry 
point instead of WinMain() despite passing the 
-L/exet:nt/su:windows:4.0 argument. The reason that I wanted to 
call main() from WinMain() is that I'm hoping to write some 
cross-platform GUI code and I thought I needed WinMain() to get 
the instance handle, but I wanted it to be transparent on other 
platforms. I've found another method that might work, though, so 
I'll try that instead of WinMain().
Jun 05 2012
prev sibling parent "John Chapman" <johnch_atms hotmail.com> writes:
On Wednesday, 6 June 2012 at 02:52:39 UTC, BLM768 wrote:
 I've researched this some more, and it appears that WinMain() 
 actually doesn't do any runtime initialization. That means I 
 should be able to just call the C main from WinMain() and let 
 it initialize the runtime and call _Dmain(). The main problem I 
 have now is that as soon as I put main() in, DMD uses it as the 
 entry point instead of WinMain() despite passing the 
 -L/exet:nt/su:windows:4.0 argument. The reason that I wanted to 
 call main() from WinMain() is that I'm hoping to write some 
 cross-platform GUI code and I thought I needed WinMain() to get 
 the instance handle, but I wanted it to be transparent on other 
 platforms. I've found another method that might work, though, 
 so I'll try that instead of WinMain().

You don't have to use WinMain as the entry point for Win32 programs if that's the problem. If you need the instance handle, you can get it from GetModuleHandle(null).
Jun 06 2012