How to Make a .Lib File When Have a .Dll File and a Header File

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

How to create .dll or .lib from multiple c source and header files in visual studio?

"I would like to do the same thing in Windows 10 and visual studio (2019)..."

Here are example steps using Visual Studio 2019:

Note, because Visual Studios is by definition an IDE, it removes much of the the responsibility from the developer to know as much about make-files and command line-compile instructions. These things are done within the Visual Studios application via menus and buttons on a GUI.

  • On the menu bar, choose File > New > Project to open the Create a New Project dialog box.

  • At the top of the dialog, set Language to C++ [or C], set Platform to Windows, and set Project type to Library.

  • From the filtered list of project types, select [Console App], then choose Next.

  • In the Configure your new project page, enter some [Name] in the Project name box to specify a name for the project. Enter [StaticNameLib] in the Solution name box. Choose the Create button to open the Windows Desktop Project dialog.

  • In the Windows Desktop Project dialog, under Application type, select Static Library (.lib).

  • Under Additional options, uncheck the Precompiled header check box if it's checked. Check the Empty project box.

  • Choose OK to create the project.

Note: Content within italicized square brackets ( [...] ) is mine. See link below for original.

link below

How to generate an import library (LIB-file) from a DLL?

You can generate a DEF file using dumpbin /exports:

echo LIBRARY SQLITE3 > sqlite3.def
echo EXPORTS >> sqlite3.def
for /f "skip=19 tokens=4" %A in ('dumpbin /exports sqlite3.dll') do echo %A >> sqlite3.def

The librarian can use this DEF file to generate the LIB:

lib /def:sqlite3.def /out:sqlite3.lib /machine:x86

All of the filenames (sqlite3.dll, sqlite3.def, etc.) should be prepended with full paths.

why there is a .lib file when create dynamic .dll file?

It has to do with the difference between "implicit" linking and "explicit" linking. The one sentence answer to your question is that that .lib file, often called a "stub lib" and officially called an "import library", is necessary when you do implicit linking but not otherwise.

In implicit linking, at compile time the compiler generates external function references for calls into the DLL, then the linker needs to link those to something: it uses the import library to help it do that. The linker treats these calls as special cases; it inserts code in the executable file for finding the DLL and for calling into the DLL for specific functions.

From the point-of-view of the programmer, implicit linking behaves like static linking except the DLL needs to be somewhere where the system can find it when the application is run or the system will pop up an error dialog at application startup.

Explicit linking means that it is the programmer's responsibility to find and load the DLL and to know what functions are in the DLL and how to call into them. See LoadLibrary and GetProcAddress for details. Explicit linking is useful if usage of a library is conditional or for applications with plugin architectures in which the actual DLLs to be used may not even be known at compile time.

In general though, if implicit linking does what you need, it is easier to just do it that way.

How to use a provided DLL file with HPP header?

I'm assuming the dll is a native dll, not a managed assembly (.net dll).

Usually, the dll author adds a preprocessor definition to the build system, like DLL_EXPORT. So if the author compiles the dll, the import library (a small .lib file) will contain all functions that used the DLL_API macro. Then the author can ship the very same header to a user. Because that user won't have the DLL_EXPORT macro defined, DLL_API will resolve to a dllimport, which basically says that the annotated function is defined in the import library.

Such a header might look like this (the whole #if condition is usually in its own header file which is then included in all headers that export functions):

#ifdef DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif

extern "C"
{
void DLL_API SomeFunction(int x);
void DLL_API AnotherFunction(int x);
}

If the author builds the project (in msvc) the compiler will generate the dll file and a small .lib file, which is the import library. This lib will essentially do what you have to do now: calling LoadLibrary and GetProcAddress to resolve all the functions that have been annotated with __declspec(dllexport).

The following part is a bit speculative and I'm guessing a bit here.

All __declspec(dllimport) does, is tell consumers that this dll contains those functions. But the linker has to link a declaration to its definition (implementation) so the function must be defined somewhere at compiletime. And that place is the import library (.lib). If you don't link with the import library, you will get a linker error when you build your project.

This means simply changing the dllexport to a dllimport won't solve your problems. Without an import library your only option is to load the dll manually with LoadLibrary and search for each function.

If I were you, I'd ask the author for an example project that uses the dll. AFAIK, the only ways to use a native dll is either by linking to an import library or by loading everything manually.

Manually generating the import library from the dll

I've tested this to make sure it works.

First of all, fix the header file to either use the macros like I did in the example above, or just use dllimport directly.

Second, open the developer command prompt for VS and follow the steps from this answer. Make sure to use the correct file names and target architecture (x64 or x86). Now you should have a .lib file.

Thrid, add the lib to your project.

  1. Add the directory of the lib (place it somewhere close to the project so you can use relative paths). Open the project properties and follow the steps in this image:
    Sample Image
    Make sure that Configuration and Platform are correct (you probably want it like in the image). You can also use relative paths. Click on the Macros button to see all predefined paths available to you.
  2. Add the lib to the linker dependencies:
    Sample Image
  3. Put the header somewhere in your project where you can access it.

Now you can simply include the header anywhere in your project and use the functions declared inside it. But note that the dll file has to be placed somewhere where LoadLibrary can find it. Preferably this is the same directory where your project's executable is located.

Bonus facts

The definition file (.def) is actually very simple. The def file for my sample code above is:

LIBRARY MyLibrary
EXPORTS
AnotherFunction
SomeFunction

If I remove the extern "C" block around my declarations, my function names will be mangled and the def file looks like this:

LIBRARY MyLibrary
EXPORTS
?AnotherFunction@@YAXH@Z
?SomeFunction@@YAXH@Z

If you put those functions inside a namespace (for example FooSpace), that namespace name will also be part of the function name:

LIBRARY MyLibrary
EXPORTS
?AnotherFunction@FooSpace@@YAXH@Z
?SomeFunction@FooSpace@@YAXH@Z

Note that all extern "C" entities will ignore namespaces, meaning all extern "C" functions, variables, types, ... will be put into the global namespace, no matter if you define them inside a namespace or not.

These are also the names that you'd have to pass to GetProcAddress if you did it manually.

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.



Related Topics



Leave a reply



Submit