Page 1 of 1

Simple Managed C++ Tutorial Using .Net Classes in C++ Rate Topic: -----

#1 StCroixSkipper  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 121
  • Joined: 23-December 08

Posted 27 January 2010 - 05:28 PM

My intent is to quickly remove some of the mystery of using .Net with C++. I'm just beginning C++ code that allows me to access .Net Managed Classes.

We'll use a simple console application. In Visual Studio 2008, create a new project by clicking File>New>Project. You'll get a dialog box whose left hand column contains something like 'Visual C++'. If not, the 'Other Languages', if you've installed C++ should have a 'Visual C++' entry. After clicking on 'Visual C++' you see on the right hand pane a list of possible templates for your project. Select the 'CLR Console Application' and enter an appropriate name and location for your project.

'CLR' stands for 'Common Language Runtime'. The following shows the compiler options generated by default for a 'CLR Console Application'.
/Od /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /FD /EHa /MDd /Yu"stdafx.h" /Fp"Debug\CPPUsingDotNet.pch" /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /Zi /clr /TP /errorReport:prompt /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll" /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll" /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"

I've highlighted some of the interesting differences.

/clr Creates metadata for your application that can be consumed by other CLR applications, and allows your application to consume types and data in the metadata of other CLR components.

There is a new operator '^' described in [Link]http://msdn.microsof...2bw(VS.80).aspx[/Link] which we need to understand. It is defined a indicating a handle to an object on the 'Managed Heap.' The common language runtime maintains a separate heap for all managed objects. In the old syntax of Visual Studio 2002 and 2003, the ^ replaces the old __gc*. It is simply a handle to a managed object.

Here's a simple problem...
For each input string, create an output string which reverses the characters of each word. The input string may contain punctuation marks. Do not change the position of the punctuation marks. Let's keep it simple. Only allow for the punctuation marks ',' and '.'.

So if I my input string was:
"Now is the time for all good men to come to the aid of their country.",

our console application should produce
"woN si eht emit rof lla doog nem ot emoc ot eht dia fo rieht yrtnuoc."

Hopefully, I did that right.

So here is the code. Read the '^' as "Handle to a managed" whatever .Net class. These 'Handles' look pretty much like 'pointers' to objects. Notice args is a System::String^ or a handle to a System::String but you can find the length of args by args->Length. The 'methods' for System::String are invoked by args->somemethod(...). It feels like a pointer to an object and acts like a pointer to an object. The difference is that is lives on the managed stack.

// Cpp_ManagedCode.cpp : main project file.

#include "stdafx.h"
//
// These using statements look a lot like the using statements in C#
//
using namespace System;
using namespace System::IO;
using namespace System::Text;

//
// int main( int argc,  char *argv[]) becomes 
// int main(array<System::String ^> ^args) and argc is simply
// int argc = args->Length;
//
int main(array<System::String ^> ^args)
{
	System::String^ line = args[0];
	Console::WriteLine(System::String::Format(L"Input:  {0}", line));
	cli::array<System::String^, 1>^ parts = line->Split(' ');
	StringBuilder^ sb = gcnew StringBuilder();
	
	for (int i=0; i<parts->Length; i++)
	{
		System::String^ str = parts[i];
		System::String^ result = System::String.Empty;
		wchar_t punctuation = (wchar_t)0;
		
		if(str->EndsWith(L",") || str->EndsWith(L"."))
		{
			punctuation = str[str->Length - 1];
			str = str->Remove(str->Length-1);
		}
		for (int j = str->Length; j > 0; j--)
		{
			sb->Append(str[j-1]);
		}
		if(punctuation != (wchar_t)0)
		{
			sb->Append(punctuation);
		}
		sb->Append(L" ");
	}
	Console::WriteLine(System::String::Format(L"Output: {0}", sb->ToString()));

	//Console::Read();
	return 0;
}



Here is the nearly identical code in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bluefox_CSharp
{
	class Program
	{
		static void Main(string[] args)
		{
			string line = args[0];
			Console.WriteLine("Input:  {0}", line);
			string[] parts = line.Split(' ');
			StringBuilder sb = new StringBuilder();
			for (int i=0; i<parts.Length; i++)
			{

				string str = parts[i];
				string result = string.Empty;
				char punctuation = (char)0;
				if(str.EndsWith(",") || str.EndsWith("."))
				{
					punctuation = str[str.Length - 1];
					str = str.Remove(str.Length-1);
				}
				for (int j = str.Length; j > 0; j--)
				{
					sb.Append(str[j-1]);
				}
				if(punctuation != (char)0)
				{
					sb.Append(punctuation);
				}
				sb.Append(" ");
			}
			Console.WriteLine("Output: {0}", sb.ToString());
			//Console.Read();
		}
	}
}



Is This A Good Question/Topic? 0
  • +

Page 1 of 1