Static and Dynamic linking in Visual studio - c++

I understand the concept of Static and Dynamic linking. It is known that on Windows platform, .dll are the dynamic libraries and .lib are the static libraries.
My Confusion: I made a project in which I had to use the OpenCV libraries. Basically, I had to use the following 5 libraries of OpenCV:
-lopencv_core
-lopencv_highgui
-lopencv_imgcodecs
-lopencv_imgproc
-lopencv_videoio
For this purpose, in the properties of the project, I had to tell the compiler the path of the libraries in the Additional Library Directory of VS 2012 and I also had to tell linker about the .lib libraries which I want to use for the project. The project got compiled without any error. But when I try to ran the project, it said that videoio.dll is missing (same error for rest of the libraries too). As soon as I copied the .dll files inside the folder where the .exe was present, the project ran fine.
Question: Why did I have to copy the .dll files when I already linked the static libraries (.lib)?
Further Question: When I use Eclipse on Mac OS or Linux, I just have to tell the complier where the OpenCV libraries are present and to the linker which other OpenCV libraries I want to use. I never had to put the dynamic libraries to the .exe folder in that case.

The "usual" windows tool chains offer two "flavours" of .lib.
One is the static libraries you mention. When used, there is no associated .dll.
The other is a stripped library that is only there to hook in the code to load and fix functions pointers for the dynamic library at load time.
With dynamic libraries (the .dll) you can either load it your self (via. LoadLibrary) or you can use the stub (import) .lib you have been provided with the .dll. Favour the import .lib if one is provided.
Why did I had to copy the .dll files when I already linked the static libraries (.lib) ?
The .dll needs to be in the path, or the directory with the .exe for the loader to find it.
How do I differentiate whether the .lib file is Static library or Dynamic library?
Generally the documentation should include some level of detail about this. If they are lumped in the same folder, then I would assume the .lib is tied to the .dll. If all else fails, look at the file size; if the .lib is tied to the .dll, then it is normally small in comparison to the .dll.

Related

How to link a *lib [duplicate]

There are things that I don't understand when it comes to linking... I'm writing a program using a 3rd party library (the GEOS library). This program has a dependency to geos.lib but still needs geos.dll to run.
I read this question, I think I understand the difference between static and dynamic libraries. What I don't understand is why I still need a dll when I statically link a library.
There are 3 kinds of libraries on Windows:
object library (*.lib)
import library (*.lib)
dynamic library (*.dll)
object libraries are statically linked. They contain the full object definitions of the code abstracted by the library.
import libraries is a special form of an object library. Instead of containing code they contain information for the linker that ultimately maps the executable file to the dynamic-link library.
dynamic link libraries, like object libraries, supply code for your program. However, this code is loaded at runtime and not compiled into your exe.
You don't always need to link an import library. Instead you can call LoadLibrary() and lookup the API entry points by name or ordinal. (You always have to tell the code which DLL and where in that DLL's API you want to enter.)
The other comments here are correct in that you cannot make a DLL into a static lib without recompiling the code for the libary -- it is a different kind of output.
It's not statically linked. The .lib is just a stub library that binds in the .dll on windows. That is, you link with the .lib at compile time, and then at runtime it will go looking for the .dll.
If .lib was created by Visual Studio then check value of Project properties -> Linker -> Input -> Module Definition File. If it's not empty then link.exe create stub library instead of static library even if Project properties -> General -> Configuration Type is "Static library (.lib)".
You are definetely linking to a dynamic library.
Just because the linker requires .lib file doesn't mean you're linking to a static library.
You can statically link the lib file if and only if this is a static lib file. So first you need to convert your dll's project to the static lib, build it and after that use the product of your build which will be a static .lib file.

Are lib files exclusively statically linked or do they need to be compiled specifically (VS2015)

I have some confusion about static and dynamic linked libraries and .lib and .dll files.
I have a project with two libraries, one I built myself and one is from an open source library.
The one I built myself is a separate project in the same solution (Visual Studio 2015, C++), and I don't need to copy over the .lib files or create a DLL for the executable to build and run
For the other open source library, I do need to copy over the .lib file and the DLL into the executable folder. However, I thought it would be possible to statically link a .lib file and not have to copy over the DLL.
Does this mean I need to compile the Open Source library differently? Like change the define __declspec(dllexport) to __declspec(dllimport) ? Or change /mD to /mT in compiler options?
I tried both of these, but it's still saying that it can't start without the .dll
Or can I get away with changing a setting in the executable project to link this library statically? If so, what are these settings?
EDIT: I know this is a standard question that can be looked up on google, but I haven't been able to find an exact answer for a while. Mainly, I'm confused about what settings need to be changed, and which project they need to be changed in. (The library or the executable).
I'm under assumption that static linking means the library is built into the executable, and dynamic linking means the library needs to be in a separate file, if this is incorrect, please let me know. Otherwise, I need to know how to build the library into the executable file.
And I can go ahead and change the build options in the open source library, and I tried this already.
Thanks,
-D
In Windows, dll files (dynamically linked libraries) need to be in the same directory as the application or on the search path. lib files (static libraries) need to be statically linked during linking (the last step of building the application). It's common in Windows so have a library come with both a dll and lib file. In this case, the lib file is an import library containing the information needed to easily link to the dll.
Place the dll file where your application will be built and statically link with the lib file. Go to 'Project->Properties->Link->Input->Additional Dependencies' and 'Project->Properties->Link->General->Additional Library Directories' to specify the static libraries you want to link.
Edit: It seems I misunderstood the question. The question is how to recompile a dynamic library as a static library. You need the source code of the library you are using along with it's Visual Studio Project file. Open the library and in `Project->Properties->General->Configuration Type' change it from Dynamic Library to Static Library.
Beware that Dynamic Library uses the Linker group of properties while the Static Library uses the Librarian group of properties. Changing between these types may cause the project to drop essential linker flags options. Since every library is different, I can't predict what you will have to do work around this. Make sure to backup the project file so you can see the original options and flags.
I had to change the setting for "Static Library" for All Configurations, not just Debug, although it was building in Debug. Not sure what may have caused this. Possibly because the debug and release builds for the library were set to the same folder, it may have been overwriting the debug builds with release builds when building

Are there different types of .lib files?

I've compiled a minimal example of code using Qt, and noticed that linking to its .lib files added a requirement for my compiled program to link to its corresponding .dll file.
I want to create a .lib myself for one of my other projects to use, but want to do so without having to also make a .dll for it to have to link to.
From the answer to this question: Difference between static and shared libraries?
Static libraries are .a (or in Windows .lib) files. All the code relating to the library is in this file, and it is directly linked into the program at compile time. A program using a static library takes copies of the code that it uses from the static library and makes it part of the program. [Windows also has .lib files which are used to reference .dll files, but they act the same way as the first one].
Am I correct in understanding that there are two types of .lib files:
a type that copies the code in it into the compiled program (removing the need for a .dll link)
a type that adds references to a .dll file into the compiled program
If this observation is correct, how would one go about compiling a .lib of one of these types?
Yes, in this sense, there are two types of .lib files. This is specific to Windows (or, more exactly, to DLLs).
On Windows, a static library is a single file, normally with the extension .lib. Linking against a static library copies the code (object files) stored in it into your executable. This is equivalent to .a files of the Unix world.
A DLL (a shared library), on the other hand, has two parts: the dynamically-loaded library itself (.dll) which contains the code, and an import library (.lib) which contains sort of "stub code" for satisfying linker dependencies. You link against an import library (the .lib files accompanying the DLL), and that includes the "stub code" for the DLL's functions, and also marks your executable as requiring the DLL to load at startup.
In Visual Studio, you can select the project type for each project: either Static library (will produce .lib file) or Dynamic library (will produce .dll file and its corresponding .lib file).
In the Unix world, this works differently: a shared library (extension .so) is itself used during linking, and that creates the loader dependency.

Linking OpenCV static libraries in Eclipse Windows

I want to create an executable that I can move to another computer that does not have OpenCV installed.
As such I am trying to statically link all the libraries needed into the executable (Thats what its called right?).
The program compiles just fine and works on my local computer but when I copy it to another computer it complains that it is missing .dll files and won`t execute.
I am using eclipse juno with mingw as compiler on windows 7.
My progress so far:
I have included the libraries needed from opencv\build\x86\mingw\lib into the MinGW C++ linker -> libraries in the project properties.
opencv_core244.dll
opencv_highgui244.dll
opencv_imgproc244.dll
In the original folder these are called:
libopencv_core244.dll.a
libopencv_highgui244.dll.a
libopencv_imgproc244.dll.a
I have set the linker flag in MinGW C++ Linker -> miscellaneous to -static.
I have been searching a lot for answers and have tried a few different things but I`m really stumped by this.
How do you force the compiler in eclipse (MinGW in this case) to link the libraries as static libraries and not as dynamic libraries as it is apparently doing?
1) If OpenCV has been compiled to be used as DLLs, then you can not link statically.
2) Remember when you compile the project for DLL output then you have a .lib file. This .lib file is not actually a static library with code. It is used by the compiler to know the DLL name for class/function definitions. This will need the DLL at runtime.
3) For static linking you need .lib file which compiled as static library. In such compilation there is only one output which is a .lib file. This .lib file can be used for static linking and the code from .lib file is added to your application.
4) I have just compiled one project with VStudio which is a DLL having only one function. I get a DLL and a .lib as output. The size of the .lib is 2kb.
5) When I compile the same project as static library, then I get only one output that is .lib file. Its size is 133kb.
This is almost a year late with the clarification/answer, but hope it can be some use to you or anyone else who comes across this page with the same problem.
While Pruthviraj didn't clearly explain his answer, he had the right idea. By default, the config file for cmake has "BUILD_SHARED_LIBRARY" flag set to true. The .a files that were created simply redirected to the dll files and are in essence useless to statically link in a program.
The easiest way is to rebuild OpenCV with cmake, but make sure the flag "BUILD_SHARED_LIBRARY" is set to false. It is under the Build sub-category in cmake GUI if you are using that.
The new generated make files should produce static libraries only in the lib folder and should properly link opencv statically in your program. Hope it helps!

Program statically linked to a library but still needs dll to run

There are things that I don't understand when it comes to linking... I'm writing a program using a 3rd party library (the GEOS library). This program has a dependency to geos.lib but still needs geos.dll to run.
I read this question, I think I understand the difference between static and dynamic libraries. What I don't understand is why I still need a dll when I statically link a library.
There are 3 kinds of libraries on Windows:
object library (*.lib)
import library (*.lib)
dynamic library (*.dll)
object libraries are statically linked. They contain the full object definitions of the code abstracted by the library.
import libraries is a special form of an object library. Instead of containing code they contain information for the linker that ultimately maps the executable file to the dynamic-link library.
dynamic link libraries, like object libraries, supply code for your program. However, this code is loaded at runtime and not compiled into your exe.
You don't always need to link an import library. Instead you can call LoadLibrary() and lookup the API entry points by name or ordinal. (You always have to tell the code which DLL and where in that DLL's API you want to enter.)
The other comments here are correct in that you cannot make a DLL into a static lib without recompiling the code for the libary -- it is a different kind of output.
It's not statically linked. The .lib is just a stub library that binds in the .dll on windows. That is, you link with the .lib at compile time, and then at runtime it will go looking for the .dll.
If .lib was created by Visual Studio then check value of Project properties -> Linker -> Input -> Module Definition File. If it's not empty then link.exe create stub library instead of static library even if Project properties -> General -> Configuration Type is "Static library (.lib)".
You are definetely linking to a dynamic library.
Just because the linker requires .lib file doesn't mean you're linking to a static library.
You can statically link the lib file if and only if this is a static lib file. So first you need to convert your dll's project to the static lib, build it and after that use the product of your build which will be a static .lib file.