void* is used as a pointer to the raw byte data without a concrete type.
This is usually used...
1. In the read / write to files and to devices, when we can write any types.
2. In "diverse" functions that can accept data of different types (malloc/calloc, part of the WinAPI functions and ODBC).
3. As the descriptor is a pointer that may not be dereferenced. The si also often use a pointer to an a type in Pascal with other rules of equivalence for the blank record. But only until another diverse function like CloseHandle.
4. To ensure the so-called circuit — transmission as the context from which the function was called, which caused callback.
BOOL WINAPI EnumWindows( _In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam ); BOOL CALLBACK EnumWindowsProc( _In_ HWND hwnd, _In_ LPARAM lParam );
Here is the LPARAM, which is typically defined as a pointer, and there is a short. EnumWindows promises to pass it to a function lpEnumFunc unchanged.
(In C++ this will also use virtual interfaces, but this method, you know, language dependent and is not suitable for cross-language API.)
What happens on the side function? One of the two (consider a function written in JAVA).
1. Or invoked certain function of the device, which says: "write 100 bytes", and then working the iron.
2. Either we convert the void* to the desired type and work with it.
Types signs give three reasons.
1. You forgot about "dereferencing a pointer". To dereference, it must have a type!
2. To avoid mistakes and not to assign incompatible pointers.
3. For polymorphism in C++, giving delete x, we don't even have to store how many bytes in the block, since we know the length of the type. (There are also virtual classes, but that's another issue.)