|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis is intended as a jump-start tutorial for Managed C++ programming. It does not cover every aspect of the managed extensions, but it does cover certain areas that are often puzzling to someone coming from a C# or a native C++ background. The article assumes that the reader is familiar with the basic elements of .NET technology and that the user can understand C++ code when he or she sees it. Simple program#using <mscorlib.dll>
using namespace System;
int _tmain(void)
{
return 0;
}
For example I can write this :- System::Console::WriteLine("Hello Earth");
But if I have used a using namespace System;
...
Console::WriteLine("Hello Earth");
It's mostly a matter of readability. Some people might prefer to use fully qualified names to improve the clarity of their code. And sometimes you are forced to, as when two namespaces have classes with the same names in which case the compiler gets confused. Managed classesA managed class is a class that is garbage collected, means you don't have to __gc class First
{
public:
First()
{
m_name = "Anonymous";
}
First(String* s)
{
m_name = s;
}
String* GetName()
{
return m_name;
}
void SetName(String* s)
{
m_name = s;
}
private:
String* m_name;
};
Well, it looks more or less like a normal C++ class except that we have used
the First* f1 = new First();
First* f2 = new First("Andrew");
Console::WriteLine(f1->GetName());
Console::WriteLine(f2->GetName());
f2->SetName("Peace");
Console::WriteLine(f2->GetName());
Using the managed class is not dissimilar from using a normal old-style C++
class. Except that I cannot declare objects of type Using propertiesTake a look at the two listings below :- //Listing A
f2->SetName("Peace");
Console::WriteLine(f2->GetName());
//Listing B
f2->Name = "Colin";
Console::WriteLine(f2->Name);
Obviously the second listing is more readable. Of course using a public member variable would be a very impetuous idea and one that would result in a lot of scornful looks from most programmers. But in .NET we have properties, in fact I have some rather vague ideas that the native C++ compiler supports properties too, but since the vagueness is rather strong, I better keep quiet about that one. __gc class First
{
public:
...
__property String* get_Name()
{
return m_name;
}
__property void set_Name(String* s)
{
m_name = s;
}
...
};
If you have only a BoxingConsider the function below :- void Show(Object* o)
{
Console::WriteLine(o);
}
Rather neat, eh? It takes an object of type String* s1 = "Hello World";
Show(s1);
Compiles and works fine. Now see the following snippet of code. int i = 100;
Show(i); //This won't compile
Blast! That won't even compile. You'll get compiler error C2664: ' int i = 100;
Show(__box(i));
What UnboxingObviously if you can box, you should be able to unbox too, eh? Let's say we
want to box a value object to an Object* o1 = __box(i);
int j = *static_cast<__box int*>(o1);
j *= 3;
Show(__box(j));
Good heavens! That turned out to be rather more sinister looking than you had
expected I bet. What we do is to cast the managed object to the
Native code blocksConsider the following function. void NativeCall()
{
puts("This is printed from a native function");
}
As you can see, it uses purely normal non-.NET stuff. Obviously we can
improve execution speed if we can compile this function as native. MC++ provides
us with the #pragma unmanaged
void NativeCall()
{
...
}
#pragma managed
Now when this function is encountered during program execution, the common
language runtime will pass on control to the native platform. Obviously we must
use this whenever we have functions that use fully unmanaged functions. What's
real neat is that we call call unmanaged functions that are marked as
__value classesEarlier I had said that managed classes cannot be allocated on the stack.
Sometimes, we might have the requirement for a very simple class, often merely
for storing some values. In such cases it might be desirable to have a value
type class that can be allocated on the stack. That's where the
__value class Second
{
public:
void Abc()
{
Console::WriteLine("Second::Abc");
}
};
Now we can declare objects of type Second sec;
sec.Abc();
In fact we can even declare them on the heap. But remember this won't be the
CLR managed heap and thus we need to Second* psec = __nogc new Second();
psec->Abc();
delete psec;
More reading
|
||||||||||||||||||||||