Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What is dwmain?
#1
Question 
I'm having trouble to understand what is dwmain. I run gcc -E with the following snippet and it prints nothing. It seems it can't interpret them.

Code:
if defined(__WIN32__)
#define dwmain(a, b) \
_dwmain(a, b); \
char ** API _dw_convertargs(int *count, char *start, HINSTANCE hInstance); \
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {\
   int argc; \
   char **argv = _dw_convertargs(&argc, lpCmdLine, hInstance); \
   return _dwmain(argc, argv); } \
int _dwmain(a, b)
Reply
#2
(02-17-2022, 04:21 PM)1e9t8m29 Wrote: I'm having trouble to understand what is dwmain. I run gcc -E with the following snippet and it prints nothing. It seems it can't interpret them.

Code:
if defined(__WIN32__)
#define dwmain(a, b) \
_dwmain(a, b); \
char ** API _dw_convertargs(int *count, char *start, HINSTANCE hInstance); \
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {\
   int argc; \
   char **argv = _dw_convertargs(&argc, lpCmdLine, hInstance); \
   return _dwmain(argc, argv); } \
int _dwmain(a, b)

"dwmain" is a macro that handles the entrypoint on various platforms.

On Windows the system entrypoint is WinMain() not main() ... so the "dwmain" macro on Windows will create a "WinMain() function that calls an internal library function _dw_convertargs() which changes the WinMain() arguments into the more standard main() style arguments. It then creates a _dwmain() function with the subsequent code which gets called from WinMain().

Most other platforms "dwmain" is just a macro that converts it to "main" (iOS and Android do additional processing to launch a message loop on the entrypoint thread... so the code in "dwmain" actually gets launched on a secondary thread).

But essentially "dwmain" is a macro that allows you to define a system entrypoint the same way regardless of what platform you are on.

Hope that makes sense?
Reply
#3
(02-17-2022, 11:06 PM)dbsoft Wrote: Hope that makes sense?

The problem is I want to know what the code is after it's being preprocessed. gcc -E on this snippet only returns if defined(1) and nothing else. It's on WIN32 so of course __WIN32__ is true. But what I want to know is what actually the declaration and definition of dwmain. The code is very obscure I can't preprocess it by hand.

You see it's returning _dwmain(argc, argv) but where is _dwmain is defined? I searched through out the source code but found no where else _dwmain being used other than on dw.h.

If _dwmain is declared like this: int _dwmain(a, b) then where is the definition of it? It can't be the int WINAPI WinMain because this very function return _dwmain(argc, argv).
Please give me the preprocessed (by hand) of that snippet, I want to know what you actually wanted to write in plain C code, without macros. Thanks.
Reply
#4
(02-18-2022, 06:31 AM)1e9t8m29 Wrote: If _dwmain is declared like this: int _dwmain(a, b) then where is the definition of it? It can't be the int WINAPI WinMain because this very function return _dwmain(argc, argv).
Please give me the preprocessed (by hand) of that snippet, I want to know what you actually wanted to write in plain C code, without macros. Thanks.

Ok the way these type of preprocessor macros work is they replace anything starting with "dwmain(" and ending with ")" ... the a and b will be filled in with whatever is in those positions. 

So an entrypoint defintiion like this:

Code:
int dwmain(int argc, char **argv)
{
  return 0;
}

would result in the following code being generated:

Code:
int _dwmain(int argc, char **argv);
char ** API _dw_convertargs(int *count, char *start, HINSTANCE hInstance);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
   int argc;
   char **argv = _dw_convertargs(&argc, lpCmdLine, hInstance);
   return _dwmain(argc, argv); }
int _dwmain(int argc, char **argv)
{
  return 0;
}

The _dwmain definition starts with "int" because that was before the "dwmain(" macro.

So this one definition creates 2 functions.... the WinMain() function, which is the actual application entrypoint and a _dwmain() internal function which contains your code.

The WinMain() function does the work of converting the arguments and then calls the internal function containing your code.

Make more sense now?

Brian
Reply
#5
Thanks @dbsoft. I have another question. Does the usage of dwmain compulsory? I want to use WinMain directly.
Reply
#6
(02-18-2022, 04:07 PM)1e9t8m29 Wrote: Thanks @dbsoft. I have another question. Does the usage of dwmain compulsory? I want to use WinMain directly.

You can use WinMain(), it will just make the source code Windows only.

The macro exists so that the same source code can be used on any platform.... so if cross platform is not a concern feel free to just use WinMain() on Windows... or main() on most other platforms.

On iOS and Android dwmain() is pretty much compulsory.
Reply
#7
Just one more thing about if you use WinMain() you will probably want to call Win32_Set_Instance() with the hInstance passed to WinMain() ... this saves the application instance for use in the library internally. Most stuff works without it, but there are a few things that require the instance.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)