Compiling a static lib inside a exe - c++

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).

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

Linking a lib statically in VC++

Probably I am missing here something but that is my first time on Windows that I need to link a lib statically so that the executable won't be dependent on a dll.I do it with LIBPNG.
I do it like this:
I added libpng headers : C/C++ -> Additional Include Directories
Added library directory to the linker: Linker - > General ->
Additional Library Directories
Added linker additional dependencies:Linker -> Input
Compile the exe ok.When calling it I am getting :
"The program can't start because libpng16.dll is missing from your
computer."
Which means libpng hasn't compiled into the executable.How do I fix that without reference the whole pnglib project code into my executable project?
On Windows a .lib is a library file, usually this simply contains code that loads a dll, looksup the exported functions and provides wrappers to them. But, you can build the lib differently so that instead of these wrapper stubs, it contains the actual binary code. The operation and structure of the .lib is the same - what code it contains depends on how its built.
So, if you've built libpng16 as a 'dynamic' lib/dll pair then you will need the dll part when you deploy it. If you built it as a 'static' lib only, then you'll get what you want.
The point is - you need to build the lib in the format you want in the first place. It is not possible to take a lib/dll pair and convert it into a static lib, nor is it possible to merge a dll into your executable. (well, not possible after you've built it - perfectly possibly if you change the lib's settings and recompile to produce in static lib form, of course)

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.

Linking error -> Managed DLL to Unmanaged Lib

I have a managed C++ dll which uses a unmanaged C++ lib. I've added the lib file in the managed project's "Additional Dependencies". Unfortunately I get a dozen of std::locale already defined in msvcprtd.lib linking errors.
Any idea? Do I have to build both as dll and link them together?
You probably need to change the runtime library setting for one of your projects so that they are both the same. The "Multi-threaded Debug DLL" option in the runtime library settings means that your project will be linked against the DLL version of the runtime lirary, not that your project is a DLL. Where-as "Multi-Threaded Debug" means it will link against a .lib version of the standard library.
When you link together 2 projects that use different settings, then they end up with duplicate references. One reference from the static runtime library, and one from the DLL runtime library. This is the source of your errors.
Which setting you should pick depends on whether you want to distribute the runtime DLLs with your project (or count on the user already having them). If you want to go for this option, select the DLL runtime library, otherwise select the non-DLL version. The down side of the non-DLL version is that all the runtime library code will be embedded in your DLL/EXE, which will increase it's size.
EDIT: Actually, looking into it a bit more. This link indicates that with CLR projects (which I suspect yours is, being managed C++) you can't use the static linked option, so you need to use the "Multi-threaded Debug DLL" option for both.