How to link and built a project when your external SDK only has .dll, .lib, .h files - c++

I have an external SDK that only contains a .dll, .lib, and .h files. I'm trying to use the SDK. Nothing in the dll is readable, but the .h files have some comments about the methods.
I'm not very c++ savvy. I assume I need to load the library, then read from the dll using the methods that are defined in the .h files. Correct?
I need to know how to write a cpp project where I can link all these files, read the dll, and be able to use the methods that are defined in the sdk.
Is there a test project with the project setup where I can see how this can be done?
Any help would be appreciated.

There's several ways to achieve this, including a shortcut method using #pragma that I'm not going to recommend in case it leads you to develop poor habits.
Similarly, you can use Property Sheets, but that may seem a bit overwhelming to start with. So I'm going to give you the standard middle-of-the-road approach...
In your project settings (Alt-F7 or Project > Properties...), you need to set these options:
C/C++ > General > Additional Include Directories
Add the folder you want to be searched when using the #include directive. Without complicating this with personal preference and style considerations, just set this to the directory where the SDK's header file lives.
You can use absolute or relative paths, environment variables. Whatever. I suggest for now you just use absolute path.
Linker > General > Additional Library Directories
Same as above, but this is where the .lib file resides.
Linker > Input > Additional Dependencies
This is the name of your lib file.
Now, if you #include the SDK's header file in your project's source and compile, it should hopefully work. And the linking step should also succeed.
If not, there may be extra things you need to make the SDK play nice (such as preprocessor definitions, compiler settings, or additional dependencies).
The last thing you need to worry about is that running your program might fail because the DLL cannot be found, unless it lives in a specific place that Windows searches. Rather than mess with DLL search paths etc, you can use a Post-Build Event to copy the DLL to the same directory where your executable was built.
Still, in the project properties:
Build Events > Post-Build Event
Add a command line something like:
copy "\Path\To\MySDK\MySDK.dll" "$(OutDir)\"
Now you should be all set to go, and not have to think about it again!

Related

C++ copy only needed header file for dll from separate project

My C++ project is dependent on a huge project. My project uses many dll's from huge project. It take about few hours to install the huge project and I want to remove the need to install the huge project for someone else.
After research I understand there is two methods to compile and link using dll 1) Using a lib and header.
2) Using loadlibary method.
In loadlibrary method I need to know exactly the methods needed to load. Since I don't know this I went with option 1. Please correct me if I am wrong.
Currently I have included the path to the big project in the compiler additional dependencies configuration option. I want to share the included header with my team. The big project has lot of headers that is not used by my dependency dlls. I tried copying all the headers but some .cpp are directly used without any headers.
Is there any way I can copy only the header files needed from the huge project? Possibly automatically using less manual work. Currently the headers and cpp are about 1gb which I can't share via github. If I can't copy the headers is there anyway I could automatically generate all the dependency definitions to a file and use it? Please let me know whats the standard way of handling situations like this.
You can dynamically build and link to the library (dll).
To do so, you need to
include the folder containing the .h files with the compiler -I argument -IC:\path\
link to the folder including the dll with the linker -L argument -LC:\path\
The lib has to be compiled with the same compiler & same platform

Path of least resistance when unit testing C++ code in an exe, in Visual Studio 2012

I'm in need of some sage advice here. Long story short, I'm rebuilding a - for me - relatively complex app comprised of about 7000 lines of code. I ran into a number of issues when I created the first iteration of my application and it seems to me that test driven development might just be the ticket.
I was pleased to see that Visual Studio 2012 now natively supports TDD in C++, so I went ahead and read as much as I could. Unfortunately, Vs2012 is fairly new and I feel the documentation is somewhat lacking. But this is a little beside the point. I'm relying mainly on the following guide on the MSDN site:
http://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef
It fairly clearly states that if the code under testing is to be built as an .exe, then the way forward is creating a separate test project and linking the output object file. I'm guessing they mean the object files? Or maybe not?
I'm honestly a little confused as to how many .obj's I need to link. At first I thought I needed to link every single obj file which is fairly tedious.
If anyone has experience doing this and could perhaps also recommend which macros or similar short cuts to use in order to make this process as painless as possible, I'd be much obliged!
This will depend on how you have your solution structured. The way I like to structure my solutions is to have three projects.
A .lib project that has my source code in it.
An executable project, linked with the .lib. This calls into the .lib in the main() call
A test project (exe), linked with the .lib.
With this structure you can use the Add New Reference... button in the Common Properties section and the references will be sorted for you (except the header include path found in C++\General\Additional include directories).
If you do not want to restructure your projects you can tell the linker about each obj file (Linker\Input\Additional dependencies). This may be a significant number of .obj files if you have a lot of classes that you want to test. Unfortunately, you may have issues if you use pre-compiled headers.
I would suggest restructuring the projects if you can.
There's a nifty option when you use a project dependency, that lets you choose between linking the output file or having the IDE automatically select all the object files from the other project as dependencies.
(Don't worry about the .NET stuff in the screenshot, this was taken from an project where a C++/CLI DLL included a native static library project. Just do the same thing with a native test project including a native DLL or EXE project, choosing to link with the inputs.)
Unit Test Project for a Native Application (.exe) Project
Add the Unit Test Project to the Solution
Right Click on the Solution, Add, New Project. Under Visual C++, choose Native Unit Test Project.
Add the Application as a Reference to the Unit Test Project
Right click the unit test project, Properties, Common Properties, References: Add the .DLL project as a reference. This tells MSVC to rebuild the application if it has changed since the last unit test build, before rebuilding the unit test project.
Tell MSVC to Where to Find the Application's Library and Object Files
Right click the unit test project, Properties, Linker, General: Edit Additional Library Directories and add the path(s) to your applications object and library files.
Collect all the .obj and .lib Names
Run this batch file from the subdirectory or subdirectories where your Application's object and library files are located, concatenate the .txt files if there is more than one directory. For convenience you might want to add the .txt file to your project.
: *** CollectObjLibFilenames.bat ***
dir /B *.obj > ObjLibFilenames.txt
dir /B *.lib >> ObjLibFilenames.txt
Tell MSVC to Link the Application Object Files to the Unit Test Application
Right click the unit test project, Properties, Linker, Input: Edit Additional Dependencies and add the application object filenames and library (.obj and .lib) file names (copy and past the files from ObjLibFileNames.txt).
If your Application project uses precompiled headers, don't forget to include the precompiled header object file(s), usually
stdafx.obj, If you omit it, you will get a LNK2011 error.
Microsoft says "If you use precompiled headers, LINK requires that all of the object files created with precompiled headers must be linked in."
I thought there would be a name collision if I added the object file containing my application's entry point, main(int argc, char *argv), but my unit test projects link successfully with or without main.obj. I have not tried linking a file with other entry point flavors (WinMain, wWinMain, wmain). If you have a name collision with one of those, you could aways change the name of your entry point (which would be weird): Properties, Linker, Advanced, edit the Entry point, and rename the Application's entry point function correspondingly. The option is not specified in the unit test project I just looked at, which I assume means default, which almost surely is main(int argc, char *argv).
My main.cpp files have only one function (main) and no globals, i.e. no other part of the application refers to anything in main.cpp. I assume you can get away with omitting any object file if nothing in it is referenced by a linked file. Not worth the effort to figure out which satisfy that requirement for small applications. For large applications...good luck with that; Eventually you'll want to test all your execution paths anyway.
You will likely have a precompiled header object file, stdafx.obj file in the unit test project as well as the one in your application project. That will not be a problem, as the default object file names for the precompiled header files are $(TargetName).pch, where $(TargetName) resolves the project name. I.e., the pch object files will have different names.
Suggetion: Rather than copying the contents of my application's stdafx.h file into the corresponding unit test file, include the application's stdafx.h in the unit test project's stdafx.h file, so you don't have to update the unit test's version when the application's file changes. #include <stdafx.h> works, but I use the relative path between the two projects (if their relative paths are stable), or the full pathname of the application's source file if that's more stable, to be sure the right file is found. See difference-between-include-hpp-and-include-hpp for an unsettling explanation about how #include"header.h" and #include are interpreted. Spoiler: it's another implementation specific feature of C++.
_________________________________________________________________________
As an aside, precompiled header files are specified on a per source file (.cpp) basis. An individual .cpp file can use only one precompiled header file, but you can have more than one precompiled header file in the same project. See this:

How do you add a C++ project reference in Visual Studio?

In C# it's pretty simple to add a project reference that will build the dependency, put the resulting assembly in the original's Debug/ directory and properly compile against that assembly.
So at the moment, I have a project with the Main() and a static library project in one solution. However, when I compile the Main() project and I look in the bin/Debug/ directory I don't find either the Static.lib file or the .obj files, which I think would need to be there, or something... I'm getting linker errors.
I think maybe I have to Configure the project to find the .obj and the .lib file produced by the static library project (which compiles fine, and actually produces those files.)
I'm missing something, and I'm not very well versed in Visual Studio with C++.
How do I add the reference in the Main project to use the library produced by the static library project?
The first thing you'll have to unterstand is, that static libraries are nothing like .NET assemblies. They are linked into the .exe and are not distributed as separate entity.
Your linker errors are most likely a result of you not linking to the library.
There are several ways to define libraries that have to be linked.
One is int the project settings under linker -> input -> additional dependencies,
the other would be the cheap route via #pragma comment(lib, "path to library")
You can add the name of the .lib files you need by going in project property->Linker->Input->Additional Dependencies
Then you will have to give the folder where your library is in VC++ Directories->Library Directerories.
Here is a very comprehensive answer: visual c++: #include files from other projects in the same solution
It describes the settings for the linker but also other essentials when referencing another C++ project. (especially when coming from C# but not being too versed in C++)
In .NET, one of design goals was due make this process a lot easier and automatic. Mission accomplished there.
In the native C++ world, the process is much more manual. Here is roughly my process for hooking up different modules together.
Include all relevant modules in the solution.
Set the output
directory of each project to the same directory. Either Right click
on each project, choose properties and in general, set the output
directory to: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget).
For reduced headaches, Set this for all configurations and platforms.
Then all the files will be placed in somewhere like
\your-solution\bin\Debug\x64.
Set the project dependencies - Right click on each project that will be linking to another -> Choose Build Dependencies and select the referenced projects.
Set up the linking process, by Right clicking on the calling project and choosing
properties. Go to linker -> Input and add: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget)\MyLibrary.lib
For the actual functions that are going to linked to, I set the
function declarations to something like (There are a lot of variations on the function declaration, a bit outside of the scope here):
#define DllExport __declspec( dllexport )
extern "C" void DllExport WINAPI` Testing();
In actual cpp file of the calling function, I add something like the following:
#include "..\MyLibrary\mylibrary.h"
Then in the actual calling function. simply add called function:
Testing();
If you are building multiple projects in the same solution, use a project reference to automatically link your libraries and executables together:
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-items?view=vs-2019#projectreference
which is explained pretty well here:
https://milania.de/blog/Project_references_in_Visual_Studio_and_C%2B%2B
The advantage to this approach, is that the build order will be correct. Using Additional Dependencies, as suggested in the other answers, will not maintain the proper build order.

How can you Call a method from a diffrent Project, both in C++?

I'm normally working in c# so certain things in c++ keep confusing me alot (they seem so diffrent yet the names almost the same)
I created a Console project in which i want to run a diffrent project for testing purposes. i added the project as a reference to the console app, and then got kinda stuck.
there is no namespace in the projects, so i can't do a using and if i try to include the other file, it cannot find it (and i want to avoid being unable to debug through it all).
the code for the class can be found here(ignore the c# part), the console is just a standard console with nothing in it yet.
Yeah, C++ doesn't have the notion of assemblies that exists in C# and .NET. It makes tasks like this slightly more difficult, a virtue of the fact that C++ compiles directly to native code.
Instead, you'll generally #include the necessary header files (*.h) at the top of your code file, and instruct the linker to link to the appropriate .lib file(s). Do that by going to your project's Properties, selecting Linker -> Input, and adding the file to the "Additional Dependencies" section.
As an alternative to linking to the .lib file, you can use Visual Studio to add a reference to the other project, if it's part of the same solution. Microsoft has a walk-through on creating and using a dynamic link library in C++ that might be worth a read.
I'll assume you're using Visual Studios:-). You have to tell
the compiler where to look for its includes. Under Visual
Studios, open the properties page for the project, then go to
Configuration Properties->C/C++->General, and add the necessary
directories in the entry Additional Include Directories. (If
the other project is in the same solution, use a relative path.
But I think the dialog box that pops up when you click on the
button on the right does this automatically. I'm not a great
fan of all this GUI stuff in general, but Microsoft seems to
have done this particular part quite well.)
Once you've done this, you might have to go through a similar
process for linking: this time it's under Configuration
Properties->Linker->General, and the entry is called Additional
Library Directories, but the principle is the same. (This may
not be necessary, if you're putting all of the dll's and
executables in the project in the same directory.)

Precompiled headers question

I am right now reorganizing my project and what recently was a simple application now became a pair of C++ projects - static library and real application.
I would like to share one precompiled header between two projects, but face some troubles with setting up the .pdb file paths.
Assume my first project is called Library and builds it's .lib file with a corresponding Library.pdb file. Now, the second project is called Application and builds everything into the same folder (.exe and another Application.pdb file).
Right now my both projects create their own precompiled headers file (Library.pch and Application.pch) based on one actual header file. It works, but I think it's a waste of time and I also think there should be a way to share one precompiled header between two projects.
If in my Application project I try to set the Use Precompiled Header (/Yu) option and set it to Library.pch, it wouldn't work, because of the following error:
error C2858: command-line option 'program database name "Application.pdb" inconsistent with precompiled header, which used "Library.pdb".
So, does anyone know some trick or way to share one precompiled header between two projects preserving proper debug information?
The question is, why do you want to share the precompiled header (PCH) files. Generally I woul d say, that does not make sense. PCH are used to speed up compiling not to share any information between different projects.
Since you also write about the PDB file, you probably want to debug the library code with your applications. This can be achieved by setting the /Fd parameter when compiling the library. When you link the library in your application and the linker finds the corresponding PDB file, you get full debug support.
This sounds complicated and cumbersome to set up. More than that, it may not be possible at all.
Instead, you can include the precompiled header from one application into the second. It will still be compiled once for the second project, but maintenance becomes easy and you do not have to redefine the dependencies in the second project (just include them).