Program statically linked to a library but still needs dll to run - c++

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.

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.

Visual Studio: How to specify different runtime libraries for the linker? (/MTd, MDd, etc)

I'm linking to a few libraries in VS2008. If my knowledge of the linker is correct, MTd is for static linking and MDd is for dynamic linking (to a DLL.) My goal is to statically link some libraries and dynamic link others. The project options seems to only have one setting for all libraries in the linker input. How would I do this?
Your project will be given a sensible C Runtime Library default after you set it up, depending on how you answer the New Project Wizard prompts. You can inspect and alter this (if needed) as follows:
right-click the relevant project in Solution Explorer, select Properties
look under Configuration Properties, C/C++, Code Generation, Runtime Library.
Other libraries can be linked however you want, you just specify the library to link to under Linker, Input, Additional Dependencies.
Even if you are linking to a DLL, it will still have a .LIB file (of the correct form for a DLL) to resolve external references, unless you are manually loading the DLL and discovering required function entry points.
You do need to make sure that the LIB files you link to use the same CRT as your app does, or things can go unexpectedly wrong.
No, you're mixing it up. The /MD vs /MT options is only relevant to which CRT version you link. There are two, the static version (/MT) which you should use only if you don't use any DLLs in your project. And the DLL version, a version that every binary in your process can share so that you won't have heap allocation misery. The kind of misery you get into when memory is allocated by one module and freed by another.
Choosing your own libraries is entirely up to you. Mixing and matching is fine, the linker just gets another kind of .lib. An import library instead of a static library. Just keep in mind to use /MD when you use DLLs.
The linker options your describing are for the CRT only. The static version will limit how you share memory between modules.
All other libraries you use will have be linked in based on the .lib files you provide(or not) to the linker.
There are 3 ways to use a MS library
statically link static library (.lib equivelant of an .a archive of .o)
statically link the stub (.lib compiler generated loadlib/getproc) of a dynamic library
manually load a dynamic library (loadlib/getprocaddress)

Compiling a static lib inside a exe

I have a dll and an exe, both of which I have the sources to.
For the DLL I have compiled completely statically and therefore, I would assume that the the .lib is also static. However, when I include that lib in my C++ VC++ 2008 project under Linker > Input > Additional Dependencies . I set the compile mode to /MT (multi-threaded) for the exe.
Everything compiles, but when I try to run the exe, it asks for the dll! To the best of my (limited) understanding, that shouldn't be happening.
Why should I do?
The 'compile mode' setting that you are referring to is the setting for the runtime library that gets linked with whatever library or executable you produce.
If your project is set up to produce a DLL (check the main project page), then it'll still produce a DLL no matter what you're putting into the runtime library setting. What I think you want to do is change the setting on the DLL's main project page from DLL to Static Library instead of changing the runtime library setting.
Once you've done this, make sure that both the executable and library projects have the same runtime library setting (the /MT switch you refer to), otherwise you'll get tons of strange error messages if the linker is trying to match up two different runtime libraries in the same executable.
The .lib file that is created with a "static" DLL is just an import library that handles automatic dynamic linking to all the symbols in the library. The DLL itself (that is, the .dll file) still contains all the code/symbols/etc. that you expect.
Statically linking to the .lib file just saves you from manually calling LoadLibrary()/GetProcAddress(), etc. to resolve symbols within the DLL.
You'll still need the DLL itself unless you build a true static library (that is, with all the symbols & code, rather than just the imports).