www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is wrong with this boilerplate mixin?

reply AF <noemail noemail.com> writes:
Hello,

 To make Win programming simpler, I divided sample application
(winsample.d) in a standard module (modwin.d) containing the
boilerplate code, and a application (appwin.d) file.
 Both files resides in the same directory.
 However, it does not link:

 D:\temp\dlang5>dmd appwin.d
c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

c:\dm\bin\..\lib\SNN.lib(winstart)
 Error 42: Symbol Undefined _WinMain 16

 So, what to do? And, 2nd, could things be made simpler? Attached
are modwin.d and appwin.d.
Oct 22 2006
next sibling parent reply Max Samuha <maxter i.com.ua> writes:
On Mon, 23 Oct 2006 05:56:08 +0000 (UTC), AF <noemail noemail.com>
wrote:

Hello,

 To make Win programming simpler, I divided sample application
(winsample.d) in a standard module (modwin.d) containing the
boilerplate code, and a application (appwin.d) file.
 Both files resides in the same directory.
 However, it does not link:

 D:\temp\dlang5>dmd appwin.d
c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

c:\dm\bin\..\lib\SNN.lib(winstart)
 Error 42: Symbol Undefined _WinMain 16

 So, what to do? And, 2nd, could things be made simpler? Attached
are modwin.d and appwin.d.

The mixed-in WinMain is mangled like __D6appwin11__T6WinAppZ7WinMainWT3std1c7windows7windows6HANDLET3std1c7windows7windows6HANDLEPaiZi 16 instead of _WinMain 16. This might be because the compiler doesn't handle extern(Windows) properly in the template. You could declare a global delegate in modwin which will be called in WinMain (instead of directly calling your myWinMain) and attach myWinMain to it in the static constructor of appwin. Or you could use DFL or other application framework.
Oct 23 2006
parent reply AF <noemail noemail.com> writes:
 Thank you very much. But, at the moment, I would like to stay in
vanilla win32api framework.
 Second, I do not really need an workaround: it is the intended
behaviour of dmd to mangle functions that way, or it is improper
use of syntax (i.e. my fault)?.
 I simply find ugly to bear all that gc boilerplate code with any
application when things could be simpler. Any reason why not all gc
code should be directly integrated in phobos (or dmd) WinMain
function? (actually, why have WinMain() at all and not just main()?)
 As for delegates, could you (or someone else) be so kind to
provide my an example based on the code and ideea I submitted?

 Thanks in advance.

 AF
Oct 23 2006
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
AF wrote:
  Thank you very much. But, at the moment, I would like to stay in
 vanilla win32api framework.
  Second, I do not really need an workaround: it is the intended
 behaviour of dmd to mangle functions that way, or it is improper
 use of syntax (i.e. my fault)?.
  I simply find ugly to bear all that gc boilerplate code with any
 application when things could be simpler. Any reason why not all gc
 code should be directly integrated in phobos (or dmd) WinMain
 function? (actually, why have WinMain() at all and not just main()?)
  As for delegates, could you (or someone else) be so kind to
 provide my an example based on the code and ideea I submitted?
 
  Thanks in advance.
 
  AF

Actually, you /can/ use just main(), which is my personal preferance. Just a couple of things to consider. First, in order to ensure you get an exe which doesn't pop up a console window, pass '-L/exet:nt/su:windows:4.0' to the compiler. (Or whatever would be most appropriate). Second, to get your hInstance you will need to call GetModuleHandle(NULL) and store its return. -- Chris Nicholson-Sauls
Oct 23 2006
parent AF <noemail noemail.com> writes:
Thanks for the hint. It was the hInstance I was missing up without
WinMain.

I think the official recommandation (and example) should be with
main() not with WinMain(). For all old Win programmers, WinMain
could be obvious. However, for a novice it seems pretty confusing
to change paradigm according to OS and maybe bracket everything
with version(){}.

My opinion, however.

Thanks for the submitted code (with function pointers) and for
overall help. I will give it a try.

AF
Oct 23 2006
prev sibling next sibling parent Don Clugston <dac nospam.com.au> writes:
AF wrote:
 Hello,
 
  To make Win programming simpler, I divided sample application
 (winsample.d) in a standard module (modwin.d) containing the
 boilerplate code, and a application (appwin.d) file.
  Both files resides in the same directory.
  However, it does not link:
 
  D:\temp\dlang5>dmd appwin.d
 c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
 
 c:\dm\bin\..\lib\SNN.lib(winstart)
  Error 42: Symbol Undefined _WinMain 16

If this is exactly what you typed, the reason is simple -- dmd doesn't automatically link the modwin.d file. Try: dmd appwin.d modwin.d or download build from dsource, and type build appwin.d
Oct 23 2006
prev sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
AF escribió:
 Hello,
 
  To make Win programming simpler, I divided sample application
 (winsample.d) in a standard module (modwin.d) containing the
 boilerplate code, and a application (appwin.d) file.
  Both files resides in the same directory.
  However, it does not link:
 
  D:\temp\dlang5>dmd appwin.d
 c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
 
 c:\dm\bin\..\lib\SNN.lib(winstart)
  Error 42: Symbol Undefined _WinMain 16
 
  So, what to do? And, 2nd, could things be made simpler? Attached
 are modwin.d and appwin.d.

D:\temp\dlang5>dmd appwin.d modwin.d -- Carlos Santander Bernal
Oct 23 2006
next sibling parent reply Max Samuha <maxter i.com.ua> writes:
On Mon, 23 Oct 2006 07:54:30 -0500, Carlos Santander
<csantander619 gmail.com> wrote:

AF escribio:
 Hello,
 
  To make Win programming simpler, I divided sample application
 (winsample.d) in a standard module (modwin.d) containing the
 boilerplate code, and a application (appwin.d) file.
  Both files resides in the same directory.
  However, it does not link:
 
  D:\temp\dlang5>dmd appwin.d
 c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
 
 c:\dm\bin\..\lib\SNN.lib(winstart)
  Error 42: Symbol Undefined _WinMain 16
 
  So, what to do? And, 2nd, could things be made simpler? Attached
 are modwin.d and appwin.d.

D:\temp\dlang5>dmd appwin.d modwin.d

Oops. I didn't notice that the second file was not included. Anyway, even if you include the file, the definition of WinMain will not be found because of mangling. I attached the code that uses a function pointer (i called it delegate mistakingly).
Oct 23 2006
next sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
Max Samuha escribió:
 On Mon, 23 Oct 2006 07:54:30 -0500, Carlos Santander
 <csantander619 gmail.com> wrote:
 
 AF escribio:
 Hello,

  To make Win programming simpler, I divided sample application
 (winsample.d) in a standard module (modwin.d) containing the
 boilerplate code, and a application (appwin.d) file.
  Both files resides in the same directory.
  However, it does not link:

  D:\temp\dlang5>dmd appwin.d
 c:\dmd\bin\..\..\dm\bin\link.exe appwin,,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 c:\dm\bin\..\lib\SNN.lib(winstart)
  Error 42: Symbol Undefined _WinMain 16

  So, what to do? And, 2nd, could things be made simpler? Attached
 are modwin.d and appwin.d.


Oops. I didn't notice that the second file was not included. Anyway, even if you include the file, the definition of WinMain will not be found because of mangling. I attached the code that uses a function pointer (i called it delegate mistakingly).

I don't use Windows, so I can't test your code, but I think it should work. Why don't you try going from the beginning? Just a simple module with a WinMain, see if it works. Then try to use the function pointer from within the same module, see if it works. And then split it. Good luck. -- Carlos Santander Bernal
Oct 23 2006
parent AF <noemail noemail.com> writes:
Thanks, but I think simpler than that is almost impossible: all I
did was to cut & paste...
Oct 23 2006
prev sibling parent BCS <BCS pathlink.com> writes:
Max Samuha wrote:
 
 Anyway, even if you include the file, the definition of WinMain will
 not be found because of mangling. I attached the code that uses a
 function pointer (i called it delegate mistakingly). 

you might try: extern(C) WinMain But that's just a wild guess
Oct 23 2006
prev sibling parent reply Max Samuha <maxter i.com.ua> writes:

Oct 23 2006
parent reply AF <noemail noemail.com> writes:
Thanks for the code. I also implemented a simple win app using the
main() function (see below file swapp.d).
 While I preffer this simpler form, what I need to know if I will miss
some functionality specific to the WinMain paradigm. File compilation
uses the -L/exet:nt/su:windows:4.0 parameter.

Thanks in advance.

 AF

-------------file swapp.d-------
import std.c.windows.windows;

HINSTANCE hInstance;

int main(char[][] args) {
	hInstance = GetModuleHandleA(null); //obtain the hInstance
parameter
	MessageBoxA(null,"Message text","Message title",MB_OK);
	return 0;
}

-------------end file swapp.d-----------
Oct 24 2006
parent reply Max Samuha <maxter i.com.ua> writes:
On Tue, 24 Oct 2006 19:00:55 +0000 (UTC), AF <noemail noemail.com>
wrote:

Thanks for the code. I also implemented a simple win app using the
main() function (see below file swapp.d).
 While I preffer this simpler form, what I need to know if I will miss
some functionality specific to the WinMain paradigm. File compilation
uses the -L/exet:nt/su:windows:4.0 parameter.

Thanks in advance.

 AF

-------------file swapp.d-------
import std.c.windows.windows;

HINSTANCE hInstance;

int main(char[][] args) {
	hInstance = GetModuleHandleA(null); //obtain the hInstance
parameter
	MessageBoxA(null,"Message text","Message title",MB_OK);
	return 0;
}

-------------end file swapp.d-----------

Do you know how to access nCmdShow param? User may set the initial state of the app's window (maximized, etc.) in a shortcut to your app and you'd better handle this properly. there is also a rather hackish way to use WinMain without the function pointer: modwin.d: extern(Windows) int winMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); // or you could try extern(C) to hack the D mangling :)) extern(Windows) export int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { ... result = winMain(hInstance, hPrevInstance, lpCmdLine,nCmdShow); } appwin.d: import modwin.d extern(Windows) int winMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ... } Well, that's insane... BTW, why methods with external linkage defined in mixins use D mangling? Is it a bug or feature?
Oct 24 2006
parent reply AF <noemail noemail.com> writes:
 No, I don't know how to access the nCmdShow parameter.
 Is there any possibility?

 On the other hand, about linkage and magling, I simply do not know.

 Thanks for the new code, I will give it a try.
Oct 24 2006
parent reply Max Samuha <maxter i.com.ua> writes:
On Wed, 25 Oct 2006 05:50:01 +0000 (UTC), AF <noemail noemail.com>
wrote:

 No, I don't know how to access the nCmdShow parameter.
 Is there any possibility?

 On the other hand, about linkage and magling, I simply do not know.

 Thanks for the new code, I will give it a try.

Sorry, I failed to figure out how to access nCmdShow from main(). Maybe somebody else could help? I'm sure Walter knows the answer.
Oct 26 2006
parent reply Serg Kovrov <kovrov no.spam> writes:
Max Samuha wrote:
 On Wed, 25 Oct 2006 05:50:01 +0000 (UTC), AF <noemail noemail.com>
 wrote:
 Sorry, I failed to figure out how to access nCmdShow from main().
 Maybe somebody else could help? I'm sure Walter knows the answer.   

You could use Windows API GetStartupInfo() (http://windowssdk.msdn.microsoft.com/library/ms683230) I believe STARTUPINFO.wShowWindow is what you need. -- serg.
Nov 04 2006
parent AF <noemail noemail.com> writes:
Thanks. I will do some further reading on that API.

I wanted also to know if the main() version loses some functionality
at the gc level, comparatively with the WinMain() Walter-provided
boilerplate, but I hope the question is not critical.

Thanks again.

AF
Nov 05 2006