Call managed code from your C++ code
Over the decades of writing code, I’ve found that writing managed code (C#, VB) is much more productive than native code (C++).
This is especially true due to the capabilities of the .Net framework libraries that can be used easily from managed code.
For a given programming task, the number of lines of code is much smaller with managed code, resulting in fewer possibilities of errors.
Below is a sample that takes a very raw C++ program and adds the ability to call managed code to it. This yields a mix of the power, performance of C++ with the capabilities and productivity of the .Net framework.
Start Visual Studio.
File->New->Project->C++ General->Empty Project “CppClr”
Source->Files->Right-Click->Adde New C++ File “CppClr”
Paste in this very simple example:
int main()
{
}
Hit F9 to set a breakpoint on “main”
Hit F5 to run.
You’ll see the breakpoint get hit, and that the program defaults to a Console Application, which means a Console window was created.
(You can also start with your existing C++ project)
Now we want to add some managed code. Paste in this:
using namespace System;
int main()
{
// an uninitialized managed string instance
String ^ mystr;
// use gcnew, for GarbageCollected New to create
// a managed object
// The "L" prefix means use Unicode
mystr = gcnew String(L"Hello World"); // create a new string
// call the managed code Console.WriteLine
Console::WriteLine(mystr);
Console::WriteLine(L"From C++ Managed Code!");
Console::ReadLine();
}
You’ll get some errors.
First we’ll tell the C++ compiler that we want to use Clr:
Project->Properties->Configuration Properties->C/C++->General->Common Language RunTime Support = “Common Language RunTime Support (/clr)”
These are errors which can be fixed by changing the properties:
cl : Command line error D8016: '/ZI' and '/clr' command-line options are incompatible
Project->Properties->Configuration Properties->C/C++->General->Debug Information Format: Program Database (/Zi)
cl : Command line error D8016: '/clr' and '/Gm' command-line options are incompatible
Project->Properties->Configuration Properties->C/C++->Code Generation->Enable Minimal Rebuild: No
cl : Command line error D8016: '/clr' and '/EHs' command-line options are incompatible
Project->Properties->Configuration Properties->C/C++->Code Generation->Enable C++ Exceptions: Yes with SEH Exceptions (/EHa)
cl : Command line error D8016: '/clr' and '/RTC1' command-line options are incompatible
Project->Properties->Configuration Properties->C/C++->Code Generation->Basic Runtime Checks: Default
CppClr.cpp(5): error C2653: 'Console' : is not a class or namespace name
CppClr.cpp(5): error C3861: 'WriteLine': identifier not found
CppClr.cpp(6): error C2653: 'Console' : is not a class or namespace name
CppClr.cpp(6): error C3861: 'ReadLine': identifier not found
These errors mean we need to add references to some CLR assemblies. However, the project file thinks this is not a CLR project, so the Framework assemblies don’t show in the Add ref dialog.
We can fix that: Right Click on the CppClr Project node in the Solution Explorer->Unload Project.
Then Right Click ->Edit CppClr.vcxproj
That opens the file in the editor.
Add the line
<CLRSupport>true</CLRSupport>
To each configuration(Debug and Release) as shown below:
Now save and close the file, Right Click->Reload the project
Now we can add framework assembly references:
Project->Properties->Common Properties->References->Assemblies->Framework
Add System
Now you have added managed code to a C++ project!
Ctrl-F5 to run it without debugging.
Comments
Anonymous
December 12, 2013
I followed the instructions as described above and after changing this setting and running my program: Project->Properties->Configuration Properties->C/C++->Code Generation->Basic Runtime Checks: Default My output shows: Fatal error: could not initialize the COM library Press ENTER to shutdown... I get many warnings about "Cannot find or open the PDB file" I need help!Anonymous
November 20, 2015
Thanks, that was helpful and the first 2 steps fixed the error but obviously the solution stops creating debugging information so can't debug the project but still at least I can run it! Thanks.Anonymous
November 20, 2015
I had selected /ZI to none, setting it to /Zi works just fine and it does create debug info. Great!Anonymous
February 03, 2016
Thanks for the information, it really helped a lot!!!