Creating C++ DLLs with Visual Studio - c++

I am creating a simple C++ DLL project using Visual Studio 2008 Express Edition.
I have a few classes inside a namespace, and a few non-static functions and constructors inside it are declared with __declspec(dllexport).
All those functions are implemented.
I also have an extern "C" BOOL APIENTRY DllMain function which simply returns TRUE.
As I hit Debug(or Release), it successfully builds with no errors nor warnings.
The output folder(either "Debug/" or "Release/") gets files such as "BuildLog.htm", one ".obj" file per source file, "vc90.pdb", "vc90.idb", "[DLLNAME].dll.embed.manifest", "[DLLNAME].dll.embed.manifest.res", "[DLLNAME].dll.intermediate.manifest" but... not the DLL itself.
This is the first time I try to compile this project(so I never sucessfully compiled before) and I have little experience with C++/DLLs, although I do know standalone C++ and created Linux C shared objects before.
What am I doing wrong? Is there any particular required file that I'm missing?

I'd look up a little higher in the directory structure (the one that the solution is in) and see if your Debug/Release folders (with the DLL) are there.
I think the default is to put the actual DLLs in folders in the solution directory, not the project directory (I think the assumption is that you want all the DLLs that you build for a solution to go to the same place)

Right click on <ProjectsName> in Solution Explorer View, select Properties, go to Configuration Properties > General tab and check out the Output Directory field. The path may consist of some macros like $(SolutionDir)$(ConfigurationName) etc. Click on it, select Edit and then when a window pops up choose Macros to see what they actually mean e.g. which directory SolutionDir maps to. You can deduce the output dll's path from there.

Related

In Visual Studio, I don't want to commit my Debug folder, but it has the dll file in it, and if I move it project won't compile

What should I do?
Basically, I want to commit my Visual Studio 2012 project, but it has a Debug folder in it that we traditionally don't commit. Only problem is that the Debug folder has the project's dll in it, and if I move the dll to the folder's parent, the project no longer compiles.
So here's the structure:
Project Folder > MSVC_2012 > Debug folder, sln file, etc.
And in that Debug folder is the dll. How do I move that out of the Debug folder into MSVC_2012?
Your question isn't entirely clear on details, but here are some options (and ways you could improve the question):
Your question looks like an XY problem. You stated that "if I move the dll to the folder's parent, the project no longer compiles." in which case the real problem here is why it isn't compiling. We'd need more details to figure out why. You also need to be clearer what you mean by "if I move the dll" - you can't "move" a DLL before it is compiled, and if you move it afterwards, then by definition the compiling worked, so actually your statement as it stands doesn't make sense. In any case, you should probably focus on fixing your broken build rather than fiddling with it to meet the needs of your version controlling.
You haven't specified why it is a problem for the DLL file to be in the Debug folder. I assume it's because you want to commit it to your VCS (which you didn't explicitly state as your goal). In which case, are you aware that it is not normal practice to commit the binary output of your code? So one solution might be to reconsider why you are trying to commit the DLL in the first place.
You didn't specify which VCS you're using. In Git (and I assume in most other VCS') you can have finer grain control over what to exclude from commits than whole folders. So, another option is to configure your VCS to ignore the Debug folder with the exception of any DLL files contained inside it.
You can change where MSVC places your DLL file in the project property pages under Configuration Properties -> General -> Output Directory. Presumably this is what you meant when you referred to "moving" the DLL?
Finally, as per other people's comments on your question, if you want the DLL to be in both places you can use a post-build step to copy it to the relevant place. To achieve this go to the project property pages under Configuration Properties -> Build Events -> Post-Build Event then enter the relevant command (the same as you would type at a command prompt) to do the copying e.g. copy myfile.dll .., or as Alex Farber suggests, use VS macros to specify the locations in a more generalised way. See this page for a list of available macros that you can insert into the command. This should be considered a last resort solution for two reasons - (a) it is a hack, as you are redundantly copying a binary output to circumvent a shortcoming in your version controlling and/or build, when you should fix the problem at root, and (b) build events have a serious flaw in them in Visual Studio and that is that they don't allow values to be inherited. This makes them a maintenance nightmare in bigger projects.

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

Visual Studio: how to create a project that would compile 2 exe files?

So I have main.cpp and main2.cpp with int main in each. I want to get 2 exes out of it. Is it possible and what would be instruction to create such project?
Nope, Visual Studio's project model is rigidly built around the assumption that "one project generates one output".
If you need two executables, you have to create two projects. You can keep them in the same solution to make things easier for yourself, but they have to be separate projects.
Edit
Ok, as other answers have pointed out, it can of course be done, if you're desperate. You can add a custom build step, which does anything you like, including building another executable. (However, the build system won't understand that this file should be considered project output, and so some scenarios may fail: for example the file won't be automatically copied to the output folder, and when checking dependencies before a rebuild, it might not be able to understand which files to check, and what (or how) to rebuild.)
Visual Studio (at least up to 2008, not sure about 2010) also allows the use of nmake files, but then I think you're stretching the definition of "a Visual Studio project".
But under "normal" circumstances, one project implies one output. And in order to get two executables, you'd normally create two projects.
You need a solution which includes two projects. Have a read of the Visual Studio documentation on solutions and projects.
Here's my solution, since nobody in a Google search seems to suggest this method. It's quite simple and I've used/seen it used in other IDEs (like Code::Blocks).
Within your project, create a configuration for each output that you want. Then, only include one main source file in each configuration.
In VS, this means for each source file with main: right-click -> Properties -> Excluded From Build = Yes. So, once you're done, only one main source is built for each configuration. You can then specify a different output for each configuration in the Project Properties. I did this on VS 2010, but it should probably work with other versions.
I'm using this approach so that I can have several tests for one project, without cluttering the solution with more test projects than actual code projects.
I don't know if it can be done ,but the only change you have ,to do this ,is with custom build step.
EDIT: Since someone downvoted this ,i did a test making a dummy configuration.
In the custom build step I two Link-cmds (copied form original link-cmdline and modified it a bit) taking as input main1.obj resp. main2.obj and outputting App1.exe resp. App2.exe.
It's executed after Compiling and before linking.
It worked !
The downside is I cannot prevent (yet) the linking ot the orinal exe (which errors on duplicate main function).
Solution to this could be to have a lib project excluding the sources with main()from build and build them in the custum-step too.
So the answer to the question should : Yes ,it can be done!
You can't have more than one main() function in a single visual studio project. So you can't compile 2 executables, the only way is to make two different project in the same solution
You can create a solution with two project one for each output you want. Then head to Build menu and select Batch Build.. and select both projects.
If you want both exe files to be in one place you can specify a custom Post-build action:
For both project:
view the project properties page and in Build events select Post-Build events, then in the Command line field enter the command that will copy the output to the location you want, something like:
copy $(TargetPath) c:\yourlocation /Y
Then after you build the solution the output files will be copied to that location.
Another option you have is to use conditional compilation with sth like
main()
{
#ifdef VERSION1
call_main_logic();
#else
call_main2_logic();
#endif
}
and then define different configurations within the project. For each configuration you will then need to define preprocessor symbols appropriately (in: project settings -> configuration properties -> C/C++ -> preprocessor).
Please note, that it will be only one executable created at a time, but with switching configurations you'll get the one that does what you want at the moment.
... which may suit your needs or not, depending on more specific situation that you are in.
Edit: In addition, since different configurations create their separate output folders, you will have your both execs as outputs.

Visual C++ TDD setup

I haven't worked much with Visual Studio before. I've started a personal project in my spare time and I would like to use test-driven development since it has been a huge benefit to me in my Java development. I started this project quite a while ago, and I used CppUnit. I know there are probably other frameworks that are better, but this is what's already in place.
My Visual Stuido 2005 solution has 2 projects in it. It worked fine when the unit tests resided right alongside the application code. As the project grew in size, this became quite cumbersome and inelegant. I created a new project under my solution to house the unit tests (so it now has 3 projects). Everything went fine until I tried to build the solution. Everything compiled, but the unit test project failed to link. The output gives me 51 "unresolved external symbol" errors (LNK2019) for what seems like every function that my tests call.
As far as I can deduce, the problem is the directory structure that Visual Studio creates. Each project gets its own directory, and then below that are the object files and executables that get created. I think the problem is that, while the header files are properly included in each unit test, the linker can't find the cpp files because they are in a different directory. When it fails to find the implementation of a called function, it gives me the 2019 error.
Am I right in my evaluation of the problem? How can I fix it? Do I need to completely reorganize my projects or is it a simple configuration of the linker?
Thanks
Yes, your evaluation sounds pretty good. Try this: In the solution explorer, right click the name of the project that contains your tests and choose "Project Dependencies". Put a check by every project that it is dependent on. That should set up the linker settings so it automatically can find the correct files.
It sounds like the functions/classes that your test project is using from your main projects aren't exported. If code isn't exported, then nothing outside of the DLL/exe that the code lives in can reference it.
A common way that we handle this is to add a define to the project (in the project settings, go to Configuration Properties -> C/C++ -> Preprocessor, the first line has the defines) called something like PROJECTNAME_IMPL (make sure you do this for both Debug and Release configurations!). Then there is a header file (called ProjectNameExport.h) that anything exported includes, which contains something like the following:
#ifdef PROJECTNAME_IMPL
#define PROJECTNAME_API __declspec(dllexport)
#else
#define PROJECTNAME_API __declspec(dllimport)
#endif
Then, when defining a class (for example):
#include "ProjectNameExport.h"
class PROJECTNAME_API Foo
{
};
This has the result of exporting the class when the header file is included in a file within the project, and importing the class when the header file is included in a file in another project (that links to the first project, of course).
I always add the code to be tested to a separate static .lib file, and have the main application EXE and unit tests EXE depend on this. New code is added the .lib project, and the dependency support ensure the EXEs link with no errors. You need to make sure the EXE projects can find the .lib headers, but this will depend on your directory structure. You also have to watch that that the .lib and the EXEs are using the same CRT/MFC library (for example, when using the CRT you can statically link with it or use a DLL).
I find using libs in this way easier to maintain than adding files/headers to multiple projects.
I am using the Boost test framework but I would structure this the same no matter the TDD framework.
A good article on a similar setup can be found here:
http://www.codeproject.com/KB/architecture/Designing_Robust_Objects.aspx