When programming in Windows, how does Windows communicate with the programs that run on it?

When you incorporate a function call which is in another memory location on the disk or memory (not a function you yourself wrote and is included in the compilation), especially the Windows API, how does the compiler know where the function is located so when the program is run it can call that function?

For example, a very simple program that displays a window which reads hello world. You would have to call Windows API functions to achieve such features as creating the window, its size, colors and so on...

So basically what I am struggling to grasp is how the programs I write communicate with the platform, framework they are run on(generally windows for Windows API).


All those windows API functions you mentioned, as well as many other functions from different APIs out there available to you that you didn't write, are contained in external library files. A library is a collection of executable code, but it doesn't have a main function so it is intended to only be called by other programs that do start with main().

In order for you to use a library, in your c/c++ project, you must go to linker settings and add a .lib file reference. For example a lot of windows API is defined in OLE32.lib, user32.lib and kernel32.lib.

Libraries come in two flavors, they can either be static or dynamic. In static libraries all the code will be in the .lib file itself. With dynamic libraries, you will have a pair of .lib and .dll files. DLLs (as in OLE32.dll, user32.dll, kernel32.dll) contain the actual code but .lib is still needed in order to provide your executable with function addresses (which will get loaded into memory during execution) to call.

If you followed all that so far, there's one more piece of information missing. When a DLL gets loaded into your program's memory, at different times it will get loaded into different locations, so how does linker hard code the function address to call? To achieve this, there's a layer of indirection present. Linker hard codes addresses to a Branch (or Jump) Table, which is an array of function pointers to actual library functions. When a DLL is loaded into the process, Windows will update that "jump table" with actual addresses of where the DLL was loaded that specific time. This way your code never has to change and can always use the same function pointer, but in reality it points to a place in memory that is filled with JMP (assembly jump instructions) which then move the execution into the right library.

The interesting part is that at least 3/4th of c/c++ developers never heard about the jump table and really do not care. This is low-level stuff that is taken care of by windows and for the most part transparent to people.

As you are still a beginner I would recommend for you to stick to c (better yet c++) and just learn to be very comfortable in writing applications and using various APIs. Then take a look at Windows Internals. Very good book, but don't get discouraged if you start reading it and there are too many things you can't understand. When I first picked up a Inside COM book, it took me 3 attempts of trying to read it before I was actually able to grasp what it was actually talking about. First 2 times I simply didn't have enough background knowledge to understand that book.

  • You shouldn't need to have a LIB when using a DLL. This appears to be some local compiler/linker restriction/feature of yours. If the DLL is truly loaded at runtime through the LoadLibrary API function, you obtain the function addresses manually by calling GetProcAddress for each function. – user29079 Oct 1 '12 at 9:15
  • Though I suppose nobody actually loads the Windows API standard DLLs manually, in runtime, that would be quite cumbersome. – user29079 Oct 1 '12 at 9:22
  • 1
    @Lundin: This local restriction/features of mine allows me to write much less code and treat any DLL call as a normal C/c++ function call, and it is fully type-safe so there's absolutely no chance of stack going off the deep end because one parameter was mistyped. On my team if I find you check in code with a whole bunch of LoadLibrary calls and manually casting void* pointers when you could have easily imported a LIB, that code is not getting past code review – DXM Oct 1 '12 at 12:54

The key concept is that it's all the same stuff, all the way down. Just as you call functions to do things, those functions call system functions, which call others until at the very lowest level, there are bits connected to the outside world, where hardware like networks, keyboards and screens makes things happen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.