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.
Related
I have recently started learning how to use the inline assembly in C Code and came across an interesting feature where you can specify registers for local variables (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables).
The usage of this feature is as follows:
register int *foo asm ("r12");
Then I started to wonder whether it was possible to insert a char pointer such as
const char d[4] = "r12";
register int *foo asm (d);
but got the error: expected string literal before ādā (as expected)
I can understand why this would be a bad practice, but is there any possible way to achieve a similar effect where I can use a char pointer to access the register? If not, is there any particular reason why this is not allowed besides the potential security issues?
Additionally, I read this StackOverflow question: String literals: pointer vs. char array
Thank you.
The syntax to initialize the variable would be register char *foo asm ("r12") = d; to point an asm-register variable at a string. You can't use a runtime-variable string as the register name; register choices have to get assembled into machine code at compile time.
If that's what you're trying to do, you're misunderstanding something fundamental about assembly language and/or how ahead-of-time compiled languages compile into machine code. GCC won't make self-modifying code (and even if it wanted to, doing that safely would require redoing register allocation done by the ahead-of-time optimizer), or code that re-JITs itself based on a string.
(The first time I looked at your question, I didn't understand what you were even trying to do, because I was only considering things that are possible. #FelixG's comment was the clue I needed to make sense of the question.)
(Also note that registers aren't indexable; even in asm you can't use a single instruction to read a register number selected by an integer in another register. You could branch on it, or store all the registers in memory and index that like variadic functions do for their incoming register args.)
And if you do want a compile-time constant string literal, just use it with the normal syntax. Use a CPP macro if you want the same string to initialize a char array.
Is this a memory address ranging to (theorically) 2^32-1 on 32-bit machine?
The reason I'd like to know that is I'm trying to somehow associate a HWND returned by CreateWindow() to a class instance, so in order to know how properly store that HWND value, I need to know what's the values like, so I can see what can fit better, AA array, linked list with hash table, etc.
From the documentation for MFC (to avoid confusion: this is documentation where CWnd and "window object" in the article is a C++ class in your program, not USER32):
The Windows window, on the other hand, is an opaque handle to an internal Windows data structure that corresponds to a window and consumes system resources when present.
Opaque handles must be treated as "black boxes" or atomic blobs that must not be altered and likely won't reveal any useful information through introspection either.
Also, see Wikipedia: https://en.wikipedia.org/wiki/Handle_(computing)
To store a value you need to know its type only. As documented under Windows Data Types, an HWND is a type alias for a HANDLE, which is a type alias for PVOID, which in turn is a type alias for void*.
In other words: An HWND is a pointer to unknown data. It's pointer-sized and trivially copy-able.
How is it that certain System calls take pointers to structs as arguments? If these structs are defined in the kernel, then how can user programs create instances of them?
There is no magic here. The struct types used in syscalls and meant to be user-createable are declared in header files, just as the syscalls themselves are. Take stat(2):
int stat(const char *path, struct stat *buf);
You get the declaration of struct stat (on Linux) by including sys/stat.h.
Some types are not meant to be directly declared by client code, however. In comments you mentioned semaphores, and sem_t is an example of such. The user header provides only an incomplete declaration, so you can't create an instance directly. This is intentional. In those cases there will be a call that creates an instance and returns a pointer to it, for example:
sem_t *sem_open(const char *name, int oflag);
You are expected to provide that same pointer as an argument to subsequent syscalls, even though you can't dereference it yourself (because its declaration is incomplete). The distinction between structs and struct pointers is extremely important here.
Every time , when you create a new structure inside the kernel , it can be exported to userspace by executing "make headers_install".
So if the user space binary is built in the same machine , it would be having identical copy of the header files(typically in /usr/include).Hence system calls can specify pointers to structures as parameters.
I'm using mac os 10.9, I have a C++ program that uses freeglut library. When I try to make the project. It gives an error which I don't know if it's my fault or not. This is the message:
In file included from /usr/X11/include/GL/freeglut.h:18:
/usr/X11/include/GL/freeglut_ext.h:177:27: error: functions that differ only in their return type cannot be overloaded
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
More information: I used CMake (version 2.8.12) to generate the Makefile, and installed the latest version of Xcode and XQuartz.
Any help is appreciated. Thank you.
In glut.h and freeglut_ext.h files:
In glut.h:
#if (GLUT_API_VERSION >= 5)
extern void * APIENTRY glutGetProcAddress(const char *procName) OPENGL_DEPRECATED(10_3, 10_9);
#endif
In freeglut_ext.h:
/*
* Extension functions, see freeglut_ext.c
*/
typedef void (*GLUTproc)();
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
One of the declarations returns a function type GLUTproc (specifying a function that takes no arguments), and the other declaration returns a pointer (void*). Both functions take the same arguments (a single const char*). What the compiler says is true.
You're only seeing a complaint about "overloading" because it's C++. In C++, if a compiler thinks it's seen two different functions with the same name then each one needs to have different arguments (e.g. a different number of arguments, or distinct types).
In this case, I doubt the functions are meant to be different; they're meant to be the same, and at some point the API evolved and changed the declaration.
You need to find some way to prevent the compiler from seeing both declarations at the same time (perhaps by setting GLUT_API_VERSION). If you have to, you can #include just one of the files and see if you really need the other file (and if you did, you may have to manually declare some things to avoid a 2nd #include).
I am trying to understand the purpose of using Windows Data Types when defining parameters of a function/structure fields in a particular language. I've read explanations detailing how this prevents code from "breaking" if "underlying types" are changed. Can some one present a concise explanation and example to clarify? Thanks.
Found answer in a similar post (Why are the standard datatypes not used in Win32 API?):
And the reason that these types are defined the way they are, rather than using int, char and so on is that it removes the "whatever the compiler thinks an int should be sized as" from the interface of the OS. Which is a very good thing, because if you use compiler A, or compiler B, or compiler C, they will all use the same types - only the library interface header file needs to do the right thing defining the types.
By defining types that are not standard types, it's easy to change int from 16 to 32 bit, for example. The first C/C++ compilers for Windows were using 16-bit integers. It was only in the mid to late 1990's that Windows got a 32-bit API, and up until that point, you were using int that was 16-bit. Imagine that you have a well-working program that uses several hundred int variables, and all of a sudden, you have to change ALL of those variables to something else... Wouldn't be very nice, right - especially as SOME of those variables DON'T need changing, because moving to a 32-bit int for some of your code won't make any difference, so no point in changing those bits.
It should be noted that WCHAR is NOT the same as const char - WCHAR is a "wide char" so wchar_t is the comparable type.
So, basically, the "define our own type" is a way to guarantee that it's possible to change the underlying compiler architecture, without having to change (much of the) source code. All larger projects that do machine-dependant coding does this sort of thing.