Imagine you are a developer creating a Windows API. You have a specific set of API calls defined, documented, and released by the OS. Many of your current API calls accept structure pointers as input arguments to skip multiple input values โโwithout a huge number of input arguments.
Now developers are starting to write code for your OS.
A few years later, you decided to create a new version of Windows. You have some requirements:
- Programs compiled for a previous version of the OS should still run on your new OS - (For this, the API must be backward compatible).
- You want to expand your API - (added new API calls).
- You want to allow developers to use their existing code (which they wrote for older windows) and allow them to compile and execute it on the new OS.
OK - for your old programs to work, your new API should have the same routines with the same arguments, etc.
Now how to expand your API? You can add new API calls, but what if at the same time you want to use the old code and use some new bizarre functions without any code changes?
Usually, API procedures require a lot of information, but it is inconvenient to create procedures that have many formal arguments. Therefore, it often happens that one of the formal arguments is the apologer of the structure containing the properties that you want to convey to your routine. This simplifies the API. For example:
your old code:
struct abc { int magicMember;
Now, if you decide to expand your "someApiCall" by providing more information without changing the signature, you simply change your structure.
your new code:
// on new OS - defined in a header with the same name as older OS // hence no includes changes struct abc { int magicMember; // ;-) int a; int b; int c; int new_stuff_a; int new_stuff_b; }; void someApiCall( struct abc *p, int blaBla );
You saved the standard signature and at the same time allowed both the old and the new code to work. The only secret is magicMember , which can be considered as the revision number of the structure or - if in new versions you just add new members - the size of the structure. In both cases, your "someApiCall" will be able to distinguish between two types of the "same" structure, and you will be able to make an API call from the old and new code.
If one is picky - (s), he can say that these are not the same structures. Really not. They have the same name to prevent code changes.
For a real example, check the RegisterClassEx API call and the WNDCLASSEX structure is required