I am reading about Win32 programming with C/C++ and came across a page which defines the WinMain as:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
I understand most of this, except I do not understand where did the part WINAPI come from?
I know that this is a macro for a calling convention. That's not what I am seeking clarity on. My question is not on calling conventions.
When I look at Microsoft's documentation on C++ functions, and I read through optional parts of a function declaration, I don't see any mention of including a calling convention at any place in the function declaration. So where exactly does Microsoft in their documentation speak about including calling conventions in a function declaration?
The portion of Microsoft's documentation that you linked to refers to only standard components of the C++ language. Calling conventions are not part of the C++ specification.
The C++ specification describes how a function can declare its return type and parameters, but it does not define how those values are actually passed between caller and callee. Calling conventions dictate that, and different compilers/platforms implement calling conventions in their own ways. So the C++ specification doesn't describe calling conventions.
In Microsoft's documentation, calling conventions are referred to as Microsoft-Specific Modifiers to the C++ language. Which is technically correct, as any identifier that begins with 1-2 underscores in its name is a vendor-specific extension, and all of the known calling conventions begin with underscores in their names, eg:
__cdecl
__stdcall
__fastcall
__thiscall
__safecall
__vectorcall
__pascal
__fortran
__syscall
etc...
Macros like WINAPI, STDMETHODCALL, etc simply map to a specific calling convention (usually __stdcall, but sometimes __cdecl).
If omitted in a function declaration, the compiler decides which calling convention it wants to use (usually __cdecl).
Compilers from different vendors are not required to implement each others extensions. However, in the case of calling conventions, most compilers at least implement __cdecl and __stdcall, and agree on how they should work, for code portability. But make no mistake, calling conventions are still a vendor-specific extension to the standard language specification.
Related
I am learning the winAPI through the docs and I am kind of puzzled by this one thing. The docs use CALLBACK and WINAPI in the same example and when I tried peeking their definition, they were both defined as __stdcall. If both are defined as the same thing, what's the point of having two different definitions for just __stdcall?
Also worth noting that while peeking their definitions I also found APIPRIVATE and PASCAL which were defined as __stdcall. What's the point? Can I just replace every instance of those 4 definitions with __stdcall or is it problematic?
WINAPI is the decoration used for APIs that Windows exposes to you.
CALLBACK is the decoration used for callback functions that you pass to Windows.
Replacing them with __stdcall is problematic only insomuch as your code might ever be deemed good enough for other developers to use, who might try and use a gcc, llvm or other compiler that can target Windows, but does not support __stdcall as a keyword (except probably does as a backwards compatibility hack because of the number of times reasoning such as the above went unchallenged).
Inside the WinAPI example for D, I noticed a lot of it's functions are 'tagged' as extern. Why is this? The functions clearly aren't extern.
The extern keyword specifies the linkage. WinMain must have external linkage so that it can be accessed from outside the module. It also specifies (in parentheses) the calling convention to use when calling a method. This is called the LinkageType. Detailed information can be found at Interfacing to C - D Programming Language.
it means the function should be called with the windows calling convention which is different from the D calling convention
WinMain gets called from outside D so it must be able to get called from there
I am wondering if extern "C" is a must or not?
Only if you want to call your code from C (or a different C++ compiler, which you should treat like C).
It is to disable name-mangling.
See this article on the C++ FAQ: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
No, you use extern "C" to provide a C-linkage to your C++ functions, so they won't be 'decorated' like normal C++ functions and to allow them to be called from C (or Objective-C).
Function decoration is used to implement the C++ function overloading feature and gives each variation of the function a different signature while allowing the developer to use the name he assigned.
Your C++ functions will be exported automatically by simply not using the static keyword. However if you have implemented your C++ functions within a Windows DLL it's necessary to use the declspec dllexport/dllimport keywords to access them externally.
Use of extern "C" switches off name mangling. If you don't do this you may make if hard for a client of your DLL to import your symbols.
Remember that different C++ compilers have different name mangling rules and so your mangled exported names may differ from the names used on import.
However, since it is wrong to import a class from a DLL if you are using a different compiler than that used for the DLL, this is rather a moot point.
So, if you are exporting classes (usually a bad idea anyway) it is easier to leave mangling on. Otherwise switch it off with extern "C".
This is Line 519 of WinNT.h (BUILD Version: 0091)
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
Why do we need a pointer to an struct with a single int member with a weird name called unused?
And will we ever need to use a line of code like this one?
HINSTANCE hInstance = new HINSTANCE__;
Overall declaring different data types with the same structures, doesn't make sense to me. What's the idea behind this?
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HSPRITE);
DECLARE_HANDLE(HLSURF);
DECLARE_HANDLE(HSTR);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HKL);
The point is for the different handles to have different types so that, for example, a HINSTANCE isn't assignable to a HANDLE. If they were all defined as "void*", then there are classes of errors that the compiler could not detect.
And will we ever need to use a line of code like this one?
HINSTANCE hInstance = new HINSTANCE__;
You usually use a HINSTANCE value returned by a Windows system call; I have never seen code executing a line like that.
They don't actually point to anything to memory; they are just used to refer to objects (files, resource, semaphores, windows) when making calls to the Windows API. While they're nothing more than just indexes into kernel's object tables, the developers decided that they make it a pointer to an unused structure which would make them "opaque" and cause less confusion between other types. The DECLARE_HANDLE is a function macro that does just that - declaring opaque types for handles.
I encountered it first time and found no dedicated page on msdn. What does APIENTRY mean?
APIENTRY is an alias for WINAPI.
WINAPI itself is a definition for the type of calling convention used for windows API calls, the stdcall.
Basically this is explaining to the compiler how to handle the stack and arguments when calling this function. You don't usually need to worry about it unless you are making function pointers to these types of functions.
It's just a #define for WINAPI, which is the standard decoration for a Windows entrypoint.
#define APIENTRY WINAPI