Linking Dll in Visual Studio

Linking dll in Visual Studio

On Windows you do not link with a .dll file directly – you must use the accompanying .lib file instead. To do that go to Project -> Properties -> Configuration Properties -> Linker -> Additional Dependencies and add path to your .lib as a next line.

You also must make sure that the .dll file is either in the directory contained by the %PATH% environment variable or that its copy is in Output Directory (by default, this is Debug\Release under your project's folder).

If you don't have access to the .lib file, one alternative is to load the .dll manually during runtime using WINAPI functions such as LoadLibrary and GetProcAddress.

How to link dll in visual studio?

When you compile a DLL project, you will get a DLL and a LIB file as output. The DLL contains the actual library code; the LIB file contains stubs for the exported functions that assist the linker in emitting code to call that DLL.

This is very different from the LIB file that you get when you compile a static library. That LIB file contains all of the object code that comprises the library. All such code gets linked directly into your executable when you build it—hence the "static" part of the name.

However, the actual manner of usage is very similar. Regardless of whether you are linking to a dynamic or static library, you point the linker (using "Additional Dependencies") to the LIB file. The linker does the rest; it can tell from the LIB file what it is supposed to do.

Of course, you have to make sure it is the right LIB file. Having both projects (the DLL and the EXE) in the same solution will allow you to use project references, making the task essentially foolproof.

EDIT: You will of course not get a LIB file when you build a DLL unless the DLL exports functions. (If it doesn't export any functions, there's nothing for a client of that DLL to call, so there's no reason for a LIB file!) The simplest way to arrange for functions to be exported from a DLL is to use the __declspec(dllexport) annotation. If combined with a macro, you can arrange for it to resolve to __declspec(dllimport) on the consumer side, allowing you to use the same header file for both building the DLL and consuming it from an application. More information about that in my answer here. Alternatively, you can use a DEF file with an "EXPORTS" section.

Link to a specific .dll file in Visual Studio?

First make sure your build settings are correct for release build : MSVCP140D.dll is the debug DLL of the Visual Studio 2015 runtime; the release version of this libray is MSVCP140.dll.

When you've fixed this, then you can install the Visual C++ Redistributable for Visual Studio 2015 on the target computer where you want to run your program : this will install the missing library. Notice that the VC++ redistributable does not install the debug libraries (MSVCP140D.dll) but the release ones (MSVCP140.dll).

Another option is to rebuild your program with static linking to the Visual C++ runtime. Open the Project Properties dialog and, in "Configuration Properties -> C/C++ -> Code Generation", field "Runtime Library", choose "Multi-threaded (/MT)". This way, there is no need to install the VC++ redistributable on the target computer.

Linking dlls from subfolder - Visual Studio

No, there's no such option in Visual Studio, because it's not Visual Studio that loads these DLL's. C++ is a compiled language; Visual Studio produces executables and DLL's for Windows to run. And Windows doesn't look at Visual Studio settings when running executables - your typical user probably doesn't even have Visual Studio installed!

As for Windows checking subdirectories - it's possible with manifests but not easy.

Proper way to link static libraries with dll

Static libraries should not contain any __declspec or __attribute((dll...)) things. They are nothing more than multiple object files (usually *.obj or *.o), composed into one, single file.

All you need to do in order to use such library (either in .exe or .dll) is to include proper headers and link them - with Visual Studio it's pretty easy.

First of all, you need to know 1) where your static libraries are placed and 2) their exact names. Go to project properties and then General. Target name contains name for the output file, while Output directory indicates in which folder your .lib will be placed.

Note: This path may be different for every project! For multi-project solution, I always set this to a common path to avoid configuration problems.

Now, go to properties of project, that will consume this library (link with it). Go to Linker -> Input and then add name of your .lib to Additional dependencies (entries are separated with semicolon):

Linker input

You need to add all libraries you want have linked in. Also, folder, in which these libraries are placed, must added to Linker -> General -> Additional library directories. If all .libs are placed in the same place - good, otherwise copy them into shared location or add multiple entries to Additional library directories list.

And the last thing - remember, that you also need to include headers with declarations of functions and objects, that you want to use. Basic thing, I know, but has to be mentioned.


UPDATE

unresolved external when trying to use dll library in an external prodjects

Your problem is not related to linking at all. The thing is, that you misunderstood what, linking a static library exactly does.

I am guessing, that functions reported as unresolved are not used by your DLL, right? But you expect them to be inside it, right?

When your DLL refers to an external content (like function or variable), it is resolved at linking time - together with all dependencies. But that's all. If your static library has a function named print_sample_string(), but your DLL does not use it, it won't be attached to DLL image. Think about this carefully - why should it be?

Even more - functions, that are not dllexported explicitly won't be visible anyway. Functions have by default external storage - so basically, they are private DLL's content.

So to answer your question directly - if you need to use functions/variables from static_lib1.lib, attach it to client application - just like you are attaching it now to dynamic_lib. There is no other way. (*)


(*) Truly speaking - there is. You can create intermediate function in DLL, that is exported and call desired function inside:

Somewhere in dynamic_lib:

DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}

Somewhere in .exe:

long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib

I can't imagine, however, why would you want to do this and not simply link A.lib and use it directly.

How to link dll and lib provided by other to c++ program

  • .h Properties -> C/C++ -> General -> Additional Include Directories, put path to .h file
  • .dll The compiler does not need to know where this file is located. The main thing that it placed on the right path relative to the executable file. Usually in a folder with *.exe
  • .lib Properties -> Linker -> General -> Additional Library Directories , put path to .lib file. Then Linker -> Input-> Additional Dependencies, put .lib file name (without path)

DLL reference vs DLL Implicit Linking

Why use implicit linking when you can add it as a reference in Visual
Studio?

Visual studio does implicit linking under the hood, when you reference it, as far as my knowledge goes. I think you're a bit confused about these 2 ways. Let me explain this clearly and separately:

Implicit Linking:

Here, you have a set of translation units, which gets compiled into a shared library(.dll on windows). And a .lib file is produced along with that. That .lib file contains the function pointer declarations and the definitions of these functions lie inside the .dll. When you link that .lib file, the application will automatically look over the .dll in its path. If it finds that, it will load that. Once the .dll is loaded, you can use any function within that .dll, as you linked with the .lib. Note that the functions which are marked as "__declspec(dllexport)" will be "exported".

So how Implicit Linking is useful?

  • Multiple applications can load a .dll, if you have same code that is shared between the applications, you can slap that in the .dll.
  • It makes using the .dll easier, but it comes at a cost, you cannot "reload" this unlike Explicit Linking.

Explicit Linking:

In this case, even if you produce the .lib, you don't link with it. Rather you use the Win32API(Or your OS's API) to load the shared library. On windows you use LoadLibrary("Path/To/The/DLLFile.dll"). Which gives you a HMODULE object. Then you retrieve the function pointers manually with the function GetProcAdress(sHMODULE, "Function Name"). Lastly, you call FreeLibrary(sHMODULE). to unload the library. Note that this happens at the runtime. In this case too you have to mark your functions with "__declspec(dllexport)".

So how Explicit Linking is useful?

  • In Game engines which has C++ scripting support(like Unreal) they use explicit linking to hot reload the scripting code.
  • If you want to have a plugin system in your application

How do I use a third-party DLL file in Visual Studio C++?

As everyone else says, LoadLibrary is the hard way to do it, and is hardly ever necessary.

The DLL should have come with a .lib file for linking, and one or more header files to #include into your sources. The header files will define the classes and function prototypes that you can use from the DLL. You will need this even if you use LoadLibrary.

To link with the library, you might have to add the .lib file to the project configuration under Linker/Input/Additional Dependencies.

Link DLL and class method explicitly

The main issue is that GetProcAddress() only works with extern "C" functions. The function you want to call is a member of a class, and you haven't exported either the function or the entire class.

I typically implement this by adding a define to the DLL project, and then create a header in the DLL project that defines a macro that indicates if the function/class is exported or imported. Something like this:

// Assumes IS_DLL is defined somewhere in the project for your DLL
// (such as in the project's Properties: C/C++ -> Preprocessor)
#ifdef IS_DLL
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

And then modify your class like this:

#include "DllExport.h" // name of the header file defined above

class DLL_API Connector
{
public:
Connector(std::string _apiKey, std::string _masterCode, std::string _masterSystem, std::string _masterVersion, int INTERNAL_PARAMETER = -1);
virtual ~Connector();
std::string query(std::string method, std::map<std::string, std::string> params);
[...]
}

In your .exe, include the header for your class, and use it as usual. You also need to link to the DLL. In recent versions of Visual Studio, this is done as follows:

  1. In the Solution Explorer, expand the project for the .exe.
  2. Right click References, and select Add Reference....
  3. In the dialog, select Solution in the list on the left.
  4. Select the checkbox next to the DLL's project, and press OK.

If you end up creating multiple DLLs for your program, you'll need to change the name of the defines so they don't clash (I typically include the name of the DLL in the name of each define).



Related Topics



Leave a reply



Submit