Can't reference a library project (DLL) because .lib file is missing - c++

I'm trying to start a C++ game engine project.
I don't have much knowledge of dll's and lib's but figured the engine itself would be a dll and I would have separate dll projects such as renderer, input, etc that would be used by the engine and the engine dll would be used by the game.
I seem to have the engine project referenced fine in the demo.exe project(by adding a reference and adding the path to additional include directories) but when trying to add a reference to a renderer dll project in the engine dll project I'm getting:
error LNK1104: cannot open file 'MyPath\Renderer.lib' MyPath\LINK
Engine
Why is it mentioning libs?

Many DLLs comes with corresponding LIB libraries, that are only needed at linking stage. So basically there are 2 types of LIB libraries:
Real static library that contains all the object files
Library with only definitions for the linker, this kind of libraries comes with DLLs
So basically you need to link this LIB file in order to be able to work with DLL

So I sorted my problem. As they were new projects they had no methods implemented yet, so no lib was being created, so nothing to reference to..silly me.
One last thing though, I'm having trouble defining the dllimport/dllexport macro for a header file. I'm trying to get it to define dllexport when its the exporting project but say my project is 2 names, e.g "awesome engine" then how do I realise the export macro that apparently is created automatically? Should I use an underscore for the space?
#ifdef AWESOME_ENGINE_EXPORTS // Or AWESOMEENGINE_EXPORTS?
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif

the engine project referenced fine in the demo.exe project(by adding a reference and adding the path to additional include directories)
Some libraries can be linked statically, meaning that you need only header files (.h/.hpp) and .lib files. Other libraries might require dynamic linkage that will result into your program being dependent on some DLL files, but usually you will need to have header files to know what is in those DLLs anyway. Sometimes, which seems to be your case, you need all of them: header files, static libraries and DLLs.
Header files contain declarations, they define the structure of your classes, they declare prototypes of your functions, etc. Static libraries (.lib files) are binaries, that contain definitions of your functions, variables and so on, that need to be resolved at compile time, so when they are missing, the linker will complain. Dynamically linked libraries (DLLs) are binaries as well, but they are resolved at run-time, meaning that the time when you really need them is when you run your program.

Generally,
The library may give you it's APIs in two modes:
Dynamic: Smaller executable file, but needs its DLLs.
Static: Larger executable file, but stand-alone.
First of all, decide how do you want to use that library, statically or dynamically?! Then configure your project which the compiler be able to find header files of that library.
Then if it's necessary add LIB files to your project.
In your case: Check if you added LIB files correctly to your project or makefile, or not?

Related

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 static library causes errors in the linked library

I have a small library project that uses OpenGL (glfw and glew). Now, the project compiles fine, but when I create a new project and statically link the library project, VS starts to throw errors in the library project. Why is that?
More specifically, I get this error:
error C1083: Cannot open include file 'GL/glew.h': No such file or directory (file: trenums3d.h)
The project setup is like this: There's the library project 'Foo', which is compiled into a static library ('Foo.lib'). The application project 'Bar' links 'Foo' (I added the folder where Foo.lib resides to Bar's 'Additional Library Directories', as well as the source folder of 'Foo' to Bar's 'Additional Include Directories'). If I compile only the library project, everything works just fine, but compiling the whole solution give me the aforementioned error.
This isn't a proper answer to your question, but just an explanation of the steps required for building an application in a compiled language.
Building a project containing multiple files is a three-step process:
Creation and editing of source and header files
Compilation of the source files (this step contains many sub-steps). This step creates object files of all translation units
Linking of all object files and libraries to form the final executable
Error like the one shown in your question is emitted in the second step. Linking with libraries happens in a completely different step, and is usually done by a different program than the compiler.
To answer your question, if linking with a static library also requires linking with the other libraries that the static library depend on, then the answer is normally yes. Static libraries only contain the function in the actual libraries, you can look at a static library more as a collection or archive of object files. Static libraries does not contain any information about other libraries they depend on.
And as for your problem, with the pre-processor error, it's because you include a header file from your static library, and that header file in turn includes some header files. But the pre-processor doesn't have the secondary included header files in its default search path, so you need to add it.
This still have nothing to do with linking any library, this is a pure pre-processor issue, and is handled in step two in my list above.
I suspect the header files of your static library look like somewhat this:
#ifndef SOMECLASS_H
#define SOMECLASS_H
#include "GL/glew.h"
// ...
#endif
If you include this header file from another library or application, the compiler will open this file and will see that it needs to open GL/glew.h as well in order to be able to "understand" the definition of your class.
This means you need to supply at least the header files of glew. The only way to get rid of this is if you manage to only reference glew files from your .cpp files but not from your .h files. In some cases, forward declarations can be used, but not sure if this will work for glew.
Concerning the linker settings: In case your glew library is built statically as well, you may or may not have to supply that library file and link to it from your project. This depends on how you setup your linker for your own static library. If you have troubles in this step, create a new question.

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)

How do I include my C++ DLL in a separate project?

This question might seem obvious but I am having a lot of trouble with this, and I have ended up having to post here after a lot of searching.
I currently have two windows of Visual Studio open. One is a Win32 Console->DLL project which exports a class, and in the output directory I have:
.dll file
.exp file
.pdb file
.lib file
I have dropped the DLL file into the my other project's output directory, as I do with all DLLs, and that works fine usually. Then, I added the directory into the Linker's library directories.
But unlike most libraries I use, I think I have done something wrong or I misunderstand how this works, I have no .h[pp] files, and so I have no idea how I am supposed to include the functions into my code. I'd rather not have Windows-only hacks (I want to confine that to the DLL project only, so that it can be ported easily).
Can anyone enlighten me as to what I am doing wrong?
There is nothing 'hacky' or 'windows' specific about having .h files available to the other projects. Your .lib file will provide the necessary information to complete the build. See: How do I use a third party dll in Visual Studio C++?
Did you add the .lib file corresponding to the .dll into the other project's directory?
It is the .lib file that is consumed by the linker, not the DLL (which is consumed by the loader at run-time).
A .dll is a shared library, as opposed to a static library (.lib on Windows).
Static library must always be linked when you compile your project, and you can easily call their functions using header (.h/.hpp) files, whereas you have two options for the shared library:
static linking (at compile-time, but the way to do it is different than for a static library)
dynamic linking (at run-time)
I would advise you to read this in-depth article: http://www.codeproject.com/Articles/85391/Microsoft-Visual-C-Static-and-Dynamic-Libraries
See also the wikipedia article: https://en.wikipedia.org/wiki/Dynamic-link_library

How to "add reference" in C++

I'm new to C++ and there's something I just completely don't get. In C#, if I want to use an external library, log4net for example, I just add a reference to the log4net DLL and its members are automatically available to me (and in IntelliSense). How do I do that in non-managed C++?
Often, the library comes with 1) a header file (.h) and 2) a .lib file in addition to the .dll.
The header file is #include'ed in your code, to give you access to the type and function declarations in the library.
The .lib is linked into your application (project properties -> linker -> input, additional dependencies).
The .lib file usually contains simple stubs that automatically load the dll and forward function calls to it.
If you don't have a .lib file, you'll instead have to use the LoadLibrary function to dynamically load the DLL.
The basic concept is the following:
There are 2 types of libraries: static & dynamic. The difference between them is that static libraries, during the linking build step, embed their compiled code in your executable (or dll); dynamic libs just embed pointers to the functions and instructions that some dll should be loaded when program is going to be loaded. This is realized for you by the linker.
Now you can decide which of those two you are going to use. DLLs have many advantages and disadvantages. If developing a huge application it might be worthy to consider using DLLs with delay loading instead of static lib's. Some libs are simply delivered to you as DLLs and you have no choice. Anyway the easiest way for a beginner would be to use static libraries. That would make your deployment and test much easier, since, when dealing with DLL you have to ensure that they are found at runtime (even when using debugger), this involves either copying everything in one directory or dealing with path variables.
Usually a DLL provider (if it is intended that you should be able to deal with the library) delivers you a header file(s) and a .lib which contains the calls into the desired DLL. Some vendors (e.g. boost) only require you to include the header file and the lib is automatically linked to your executable (can be achieved through compiler prorietary pragma directive). If it is not the case you must go into the project settings of the C++ project (project properties/Configuration Properties/Linker/Input) and enter the lib file name into the "Additional Dependencies" row, e.g. iced.lib; iceutild.lib. You can also put fully qualified path names there. Be aware that you have to enter the lib file names for both configurations (Debug, Release). This is the procedure you do with static libraries and Dll equally. The only difference that DLL will require a DLL lib to be either in you app-directory or in one of the path-directories.
After that step, you still might get compiler errors if you try to link incompatible libraries. There are many reasons, why they can be incompatible. But try to first link the lib this way and see if works. If not, post again your errors here ;)
Include file(s) is(are) used to be included in places, where you would like to use smth. from the lib. Just include it and the compiler will know that the symbols must come either from another (compiled) compilation unit (compiled cpp-file=>object file) or the .lib. It will make the look up and notify you if the required symbols are not found.
Good Luck,
Ovanes
P.S. This might be hard in the beginning, but when you get used to it, it will be easy.
C++ doesn't have libraries in the sense you're thinking of. It has header files that you #include, and it has things called libraries that the linker deals with, which contain the compiled code. You need to add the libraries (.LIB files) to the linker settings.
On Windows if you're using a DLL, ideally you should have a .LIB file to go with it that is called the Import Library for the DLL, and you add that .LIB file to your linker settings.
The first thing you need to do is to #include the header file that describes the functions that are available in that library.
The actual code for the library will be in one of 2 places:
A static library (.lib)
A dll (.dll)
Depending on how the library's code is given to you (as .lib files, or as a .dll), you'll have to either:
#pragma comment( lib, "libraryname.lib" ) if its a .lib
LoadLibrary if its a .dll
Sometimes a package comes with BOTH a .lib file that you need to link to, and a .dll file. In this case you don't need to call LoadLibrary, you only need to #pragma comment( lib, "libaryfile.lib" ) because in this case the .lib links you into the .dll.
A very important detail is to put the DLL where your application can find it. Charles Petzold says:
When Windows needs to load a DLL module before running a program that requires it, the library file must be stored in the directory containing the .EXE program, the current directory, the Windows system directory, the Windows directory, or a directory accessible through the PATH string in the MS-DOS environment. (The directories are searched in that order.)
Programming windows, 5th ed
MSDN
I don't recommend using the project properties menu to link because it isn't as visible what libraries you're linking to.
See also