digitalmars.D.learn - Calling main() from WinMain()
- BLM768 (14/14) Jun 05 2012 I'm working on a cross-platform GUI library and I'd like to be
- Artur Skawina (8/11) Jun 05 2012 D main's name is not mangled (which also causes trouble if you try to de...
- Andrej Mitrovic (28/31) Jun 05 2012 GUI libraries don't have to work this way. You could instantiate an
- BLM768 (12/12) Jun 05 2012 I've researched this some more, and it appears that WinMain()
- John Chapman (4/16) Jun 06 2012 You don't have to use WinMain as the entry point for Win32
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
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
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
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
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