What's the Differences Between .Dll , .Lib, .H Files

What's the differences between .dll , .lib, .h files?

  • .h: header file, its a source file containing declarations (as opposed to .cpp, .cxx, etc. containing implementations),

  • .lib: static library may contain code or just links to a dynamic library. Either way it's compiled code that you link with your program. The static library is included in your .exe at link time.

  • .dll: dynamic library. Just like a static one but you need to deploy it with your .exe file because it's loaded at run time.

DLL and LIB files - what and why?

There are static libraries (LIB) and dynamic libraries (DLL) - but note that .LIB files can be either static libraries (containing object files) or import libraries (containing symbols to allow the linker to link to a DLL).

Libraries are used because you may have code that you want to use in many programs. For example if you write a function that counts the number of characters in a string, that function will be useful in lots of programs. Once you get that function working correctly you don't want to have to recompile the code every time you use it, so you put the executable code for that function in a library, and the linker can extract and insert the compiled code into your program. Static libraries are sometimes called 'archives' for this reason.

Dynamic libraries take this one step further. It seems wasteful to have multiple copies of the library functions taking up space in each of the programs. Why can't they all share one copy of the function? This is what dynamic libraries are for. Rather than building the library code into your program when it is compiled, it can be run by mapping it into your program as it is loaded into memory. Multiple programs running at the same time that use the same functions can all share one copy, saving memory. In fact, you can load dynamic libraries only as needed, depending on the path through your code. No point in having the printer routines taking up memory if you aren't doing any printing. On the other hand, this means you have to have a copy of the dynamic library installed on every machine your program runs on. This creates its own set of problems.

As an example, almost every program written in 'C' will need functions from a library called the 'C runtime library, though few programs will need all of the functions. The C runtime comes in both static and dynamic versions, so you can determine which version your program uses depending on particular needs.

How are Header file (.h), Library file (.lib) and DLL (.dll) files related

.lib and .dll files are both containers of executables of a Windows library (.o or .obj files), with the former (.lib) containing stuff (functions, definitions, etc) that you have to link statically to the executable file of your project. The latter (.dll) is either already present in your system or you put it into your system, and it is dynamically linked to the executable file of your project.

For Unix/Linux systems, the file-extensions are .a and .so respectively (that is, .a instead of .lib, and .so instead of .dll).

In all cases, when compiling your project you must #include one or more of the .h files provided to you by the library you are using (they are called header files), because that's where the stuff inside the executables of the library get defined.

EDIT

The main advantage of a statically linked library is that it is self-contained (no external dependencies) but it increases the size of your own executable file. The main disadvantage is that future versions must be re-compiled and re-distributed.

For dynamically linked libraries, we re-distribute just the updated library executables. The main disadvantage is that our program relies on the library being already installed on the customer's system.

How does .h, .lib & .dll works together

You have to include the header files so that the compiler understands the declarations of various types and functions that are exposed/used by the library.

The library files(lib or dll) contain the object code to which the code using the library links to.

for lib the linkage is static and happens at compile time.Using a static library(lib) causes the size of your executable to increase because the entire lib is linked in to your program.

for dll the linkage is dynamic and calls are evaluated at runtime.When using dll the size of your executable does not increase because the dll's are linked at runtime and you usually need to place them at predefined paths so that they can be linked at runtime.

Advantage of static library over dll is that your executable which uses the lib is standalone while in case of dll, the dll needs to be present at a predefined path whil running the executable which uses it.

Class library lib and dll files

You can have a library project or a DLL project. A DLL is good if it will be used by multiple exes. A lib is good if you want it to become part of an exe.

DLL projects generate both a DLL file and a lib file. The import lib file is very small and just contains a jump table so the exe can be compiled.

Libs ,DLLs and .h files

All those attribute, unused, __attribute__ are what some call GNU-ishms, that is, features specific to the GCC compatible compilers (GCC itself, Clang, ICC and others). But MS VC does not aim for GCC compatibility, so they just don't work.

The people that did the port to Windows managed to remove these construct by using a few precompiler tricks, I think in the file Utilities/PHYSBAM_OVERRIDE.h. But for those to work you have to define the macro WIN32. Do that in the project "C/C++ Preprocessor Settings" page, not in the code, so it will be defined for all the source files at once.

Alternatively, and this IMO would be the correct solution, patch the sources, and replace every occurrence of #ifdef WIN32 or #if defined(WIN32) with #ifdef _WIN32. The macro _WIN32 is always predefined in Win32 and Win64, but the WIN32 is not.

Well, technically you'd have to differentiate each occurence if the issue is about being a Windows system or about being a MSVC compiler (there is a GCC compiler for Windows). And then use _WIN32 for the system dependencies and _MSC_VER for the compiler ones.

And then, if you feel like it, send a patch to the Codeplex project.

UPDATE

About the linker error, that should be easy to fix: just add the necessary "*.lib" file or files to the project. You can add them to the Linker Property Pageof the project.

.h, .dll and .lib confusion

Actually, you need only the .dll file. It contains all the necessary code and data to run it's functions. It also contains a table that links the symbolic names of the functions (e.g. the function PrintMe), their ordinals (the number of that function in the DLL) and their addresses in the DLL.

If you want to use only the DLL, you have to "manually" get the symbols resolved:

Let's say you want to use the function PrintMe of the DLL. What you had to do is to resolve it's name (PrintMe) or it's ordinal (PrintMe is the 1st function of the DLL) to it's address. For this, you could use LoadLibrary, GetModuleHandle and GetProcAdress from the Win32 API (aka Windows SDK). Additionally, this method allows you to load the DLL at runtime (see below).

The easier way is to use the MSVC(++) features __declspec(dllexport) and __declspec(dllimport), e.g.


// your DLL
__declspec(dllexport) void PrintMe()
{
printf("Hello World!");
}

// you project to use the DLL
__declspec(dllimport) void PrintMe();

The first one (dllexport) tells the compiler to export the function. The second one (dllimport) is the interesting one: It creates all the necessary code to be able to use the function from the DLL.

For this, you need the .lib file in your project (which wants to use the DLL). The .lib file contains information for the linker to resolve the symbol name (PrintMe) to its address in the DLL. Since the .lib is statically bound, the linker can make use of it - the DLL on the contrary is bound at runtime / loading time, so the linker cannot use it. (Yes, the information in the .lib file is redundant.). Note: You cannot change the whole DLL when using this method w/o rebuilding your project with the new .lib file. Some structure changes affect the addresses of the functions in the DLL, see this SO answer.

One last difference between using the Win32 API (LoadLibrary...) and the MSVC method via __declspec is the loading of the DLL. When you use LoadLibrary, the DLL is loaded at runtime, of course (so you can catch exceptions when it cannot be found and so on). The other method loads the DLL at loading time, so you program will terminate (will not run) when Windows cannot find the DLL.

When you create a project in VS, you can activate the "export symbols" checkbox at the end of a wizard (Win32 project). That gives you some examples of exported symbols. Additionally, it introduces a macro plus a preprocessor defition plus some directives that are very useful:


// DLL header

#ifdef _YOUR_DLL_EXPORTS
#define YOUR_DLL_API __declspec(dllexport)
#else
#define YOUR_DLL_API __declspec(dllimport)
#endif

YOUR_DLL_API PrintMe();

You now can use this header file to build you DLL as your DLL project has that _YOUR_DLL_EXPORTS definition (see project properties page, C++, preprocessor). The project that uses the DLL can use this header, too, but then must not have such a name defined. When you include the header file in the project in which you want to use the DLL, the macro is resolved to __declspec(dllimport). This instructs the linker to look for this function (which is found in the .lib file) and create all the necessary code to load the DLL at runtime and resolve the symbol name.

Difference between shared objects (.so), static libraries (.a), and DLL's (.so)?

I've always thought that DLLs and shared objects are just different terms for the same thing - Windows calls them DLLs, while on UNIX systems they're shared objects, with the general term - dynamically linked library - covering both (even the function to open a .so on UNIX is called dlopen() after 'dynamic library').

They are indeed only linked at application startup, however your notion of verification against the header file is incorrect. The header file defines prototypes which are required in order to compile the code which uses the library, but at link time the linker looks inside the library itself to make sure the functions it needs are actually there. The linker has to find the function bodies somewhere at link time or it'll raise an error. It ALSO does that at runtime, because as you rightly point out the library itself might have changed since the program was compiled. This is why ABI stability is so important in platform libraries, as the ABI changing is what breaks existing programs compiled against older versions.

Static libraries are just bundles of object files straight out of the compiler, just like the ones that you are building yourself as part of your project's compilation, so they get pulled in and fed to the linker in exactly the same way, and unused bits are dropped in exactly the same way.

Do I need to distribute a header file and a lib file with a DLL?

Yes, you will need to distribute the header along with your .lib and .dll

Why ?

At least two reasons:

  • because C++ needs to know the return type and arguments of the functions in the library (roughly said, most compilers use name mangling, to map the C++ function signature to the library entry point).
  • because if your library uses classes, the C++ compiler needs to know their layout to generate code in you the library client (e.g. how many bytes to put on the stack for parameter passing).

Additional note: If you're asking this question because you want to hide implementation details from the headers, you could consider the pimpl idiom. But this would require some refactoring of your code and could also have some consequences in terms of performance, so consider it carefully

What's the difference between a header file and a library?

Think of both like this (Disclaimer: this is a really high-level analogy ;) ..

  • The header is a phone number you can call, while...
  • ...the library is the actual person you can reach there!

It's the fundamental difference between "interface" and "implementation"; the interface (header) tells you how to call some functionality (without knowing how it works), while the implementation (library) is the actual functionality.

Note: The concept is so fundamental, because it allows you flexibility: you can have the same header for different libraries (i.e. the functionality is exactly called in the same way), and each library may implement the functionality in a different way. By keeping the same interface, you can replace the libraries without changing your code.

And: you can change the implementation of the library without breaking the calling code!



Related Topics



Leave a reply



Submit