DLL's, Binding, and the whole crazy thing

Started by
1 comment, last by MJP 15 years, 9 months ago
Hello. I am a mostly self-taught game programming hobbyist (for lack of a better term), and I am confused. I have fiddled around with C++, Lua, HTML (if it can be called a programming language), PHP, SQL, and several variants of BASIC (DarkBASIC, QBASIC, BlitzBASIC, etc.), not to mention some fiddling with game engine scripts (Source's language, Torque Script, GML, etc). But I'm still stumped. I want an explanation of Libraries and DLL's. I know that they can be compiled similarly to regular executable programs (whatever that entails, I don't really know much for sure except that hitting F5 in Dev-C++ makes either a program or a long list of errors). I have seen (and been baffled) by words like declspec(dllimport) and THREAD_ATTACH. What does it all mean? How is a library different from a program? What do I have to do differently to attach a DLL to a program and be able to use it's functionality? What benefits and downsides are there to using libraries or DLL's? What, if any, is the difference between Windows' '*.dll' files and Unix's '*.so' files? What is the difference between DLLs and LIBs? What is a '*.a' file? What exactly is the "dlfcn standard"? Are these files platform-specific? Tell me as much as you can about libraries, dynamic linking, and the whole API process. It's been baffling for much too long, and I just want to know what it is. Thank you. - Nick "ShotgunNinja" Iannone
Advertisement
Have you gone through Wikipedia's page on Library (http://en.wikipedia.org/wiki/Library_(computing) )? (If you didn't understand it, that's OK, just let us know you read it). And I assume you googled for everything you asked about, and didn't understand the explanations?
I'm not very familiar with how things work outside of Windows and Visual C++, but I'll share what I know...

In Windows, a native executable is (mostly) made up of a bunch of compiled code. When you compile your C++ code to an executable, your high-level code is compile to assembly code that is specific to the processor you're targeting (which is almost always x86). Assembly code can be represented as pure binary data, which is what the processor actually runs and understands. This what makes up the bulk of your executable file: binary data that maps out to assembly code.

Sometimes rather than being compiled to an executable, code is compiled to a static library. A static library (which has the extension .lib for Visual C++ and .a for gcc/MingW) is very similar to an executable: it's just a bunch of compiled code in binary form. The only major difference is that there's executable header at the beginning of the file, which is what allows Windows to launch and execute the code. The only thing you can do with a static library is to link it to something else. In C++, you link to a static library by specifying the .lib as an import library. You then use the library's header file(s) to know the function prototypes, class declarations, and global variables. This allows you to reference those in your own code. What then happens at compilation time, is all of your code (not in the library) is compiled to machine code. After this, the linker looks for points in your code where your code needs to call code in the static library and "inserts" this code into your executable. This ultimately results in all the static library code being contained inside your executable.

Dynamic Link Libraries (DLL's) are similiar to static libraries, in that they also contain compiled machine code. The difference is that unlike a static library, the code isn't placed inside the executable that's using it. Instead it stays in the DLL. What happens is Windows will load the contents of the DLL into memory (in the virtual address space of the process that's using it), and the executable code can then call code in the DLL. There's 2 ways to use a DLL: the first is to use a DLL's import library, this is known as Load-Time Dynamic Linking. When you do this, you link to a .lib (the import library) and use a header file just like you would with a static library. When you do this, the DLL is loaded into memory by Windows and all your function calls are hooked up "automatically" by the import library. The other way to use a DLL is called Run-Time Dynamic Linking. This way requires that your program actually explicitly requests that DLL is loaded into memory, using the WinAPI function LoadLibrary. Then your program can call functions in that DLL by using GetProcAddress to get a function pointer to that particular function.

Also...

declspec(dllimport) and declspec(dllexport) are used to specify whether you're importing a function from another DLL, or exporting a function from the current DLL. When you make a DLL, only the functions that are exported will be available for use by code outside that DLL.

When you create a DLL, you need to have a function defined called DllMain. this function is called by Windows at various times to indicate the lifetime of your library. What's happening is indicated by fdwReason parameter. One of the possible values of that parameter is DLL_THREAD_ATTACH, which indicates that the executable using the library has created a new thread. You cann see the docs for all the possible parameters.

For more info on DLL's, see the MSDN documentation

This topic is closed to new replies.

Advertisement