Introduction
One of the nice things about .NET are the common base classes. These classes are essentially the API
of .NET, and are available from all languages equally. Once you know how to use a String in
VB.NET you also know how to use it in C# and C++. Once you have struggled up the learning curve for one
language you can then go on to use that knowledge in other .NET languages.
In .NET there are value types and reference types. Value types refer to simple data structures
such as int's and enumerations, and are stored on the stack. Reference types are created
on the .NET managed heap, which allows the garbage collector to track their lifetime and free instances
when they are no longer required.
Think of a reference type as a pointer - though not in the traditional C/C++ sense of the word.
The actual location of a variable on the managed heap will change as the garbage collector recovers
unused memory and compacts the heap, so in a short time a traditional pointer to a spot on the heap
will be invalid. A .NET reference, on the other hand, will always give you access to your values no
matter where it has been moved on the heap. A variable of reference type will always either contain
a reference to a value of that type, or null. Assigning the value of a reference variable to another
variable copies the reference, not the value stored. Be warned!
Value types are stored on the stack and are accessed directly. Once the memory containing that
value is freed, the value type instance is destroyed. Hence, references to value types are not
allowed. If it were allowed it would be possible to have a reference point to an invalid memory
location. A value type will always point to a variable of that type, and cannot be null. Assigning
a value type to another variable results in a copy of the value being made.
Creating an instance of a reference type
Value types are easy since they are declared on the stack. It would be insane if you had
to call new each time you wanted to create an int or double.
Reference types are a little more complicated in that they cannot be created on the stack.
Reference types are created on the .NET managed heap, and so must be created using the overloaded
new operator. The new operator for managed types not only creates the
object on the managed heap, but also initialises the value of the variable to 0. The value passed
back from new will not be a .NET reference, and not pointer in the traditional sense.
In the following examples we will concentrate on the String class. You'll use
it a lot, and it has some tricks up its sleave.
To create an instance of a reference type you simply declare a pointer of the variables type
and create the object using new.
String* s = new String("This is a string");
Attempting to declare a managed object on the stack simply won't work:
String s = "This is a string";
The String class' constructor contains many different overrides for many
different occasions, but does not contain an override for String().
Other ways of declaring a String are as follows:
String* s = new String("This is an ANSI string");
String* s = "This is an ANSI string";
String* s = L"This is a UNICODE string";
String* s = S"This is a .NET string";
ANSI and UNICODE strings should be familiar to you. .NET strings (those prefixed by 'S')
are new and offer better performance than standard C++ literal strings. As well as this, all instances
of identical string literals actually point to the same string. If s1 and s2
are two String's, then the following code:
s1 = S"This is a .NET string";
s2 = S"This is a .NET string";
if (s1 == s2)
printf("s1 == s2\n");
else
printf("s1 != s2\n");
s1 = "This is a C++ literal string";
s2 = "This is a C++ literal string";
if (s1 == s2)
printf("s1 == s2\n");
else
printf("s1 != s2\n");
would produce
s1 == s2
s1 != s2
Note that C++ literal strings can be used where ever .NET strings are used, but .NET strings
cannot be used where C++ strings are expected.
Note also the use of printf in the above snippet. Just because we are using
.NET types and methods doesn't mean we lose our standard non-managed libraries. In managed
C++ we get the best of both worlds.
Creating your own managed types
Creating your own managed types is achieved using the new __gc keyword.
__gc class MyClass
{
public:
int ID;
};
You then use this class as you would any other managed class:
MyClass* mc = new MyClass;
mc->ID = 5;
Because mc is a managed type it will be automatically initialised to 0
(ie mc->ID will be set as 0).
Using managed types in non-managed functions
The final point is that when combining managed and unmanaged code you will invariably
come across situations where you need to pass a managed pointer to a function expecting
an unmanaged (fixed) pointer.
To allow this, a new keyword __pin has been introduced that essentially
pins down the managed pointer so that the garbage collector will not move it.
MyClass __pin* pMC = mc;
printf("The pinned value of mc is %d\n", pMC->ID);
History
16 Oct 2001 - updated source files for VS.NET beta 2
| You must Sign In to use this message board. |
|
|
 |
|
 |
In our current project, to optimize efforts, one dll was written in .Net framework (with /clr settings). Now we need to access this dll from other projects which are not CLR compliant.
To do this, they have some mechanism in place –
DataExport dll is the .Net dll (/clr)
A new project DataExportingLinkActive has been created as a wrapper to DataExport dll. This project also has /clr setting in it. But it has a mix of managed and unmanaged code.
Now while compiling this project, it gives me following linking errors –
DataExportLink.obj : error LNK2019: unresolved external symbol "public: void __clrcall CDataExport::AddRowXMLChartMaster(class System::String ^,class System::String ^,class System::String ^,class System::String ^,class System::String ^,class System::String ^)" (?AddRowXMLChartMaster@CDataExport@@$$FQAMXP$AAVString@System@@00000@Z) referenced in function "public: void __thiscall CDataExportLink::AddRowXMLChartMaster(class ATL::CStringT > >,class ATL::CStringT > >,class ATL::CStringT > >,class ATL::CStringT > >,class ATL::CStringT > >,class ATL::CStringT > >)" (?AddRowXMLChartMaster@CDataExportLink@@$$FQAEXV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@00000@Z)
The help for this error says that there is an attempt to call a __clrcall method in __thiscall method. Which also means that the caller is expecting __thiscall method but it is not getting it (__clrcall method is available instead).
I have been hunting to get this resolved. But no breakthrough yet. One more clue: These projects were working fine in VS 2003. Now in VS 2005, they are giving these errors!
Please let me know if any one of you has encountered such a problem and have succeeded resolving the same.
Any kind of help would be appreciated..
Thanks in advance
Swarnima
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi I would like to know the solution for the following problem. I have an interface with a method "dothis" as given below (language is C#).
double doThis(out ArrayList); //C# interface
I would like to implement this interface in MC++, But I don't know the equivalent for the key word "out". Could you please let me know.
Siemens
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Wow, i'm having a lot of trouble implementing some C++ code. One person in our group made a module, in unmanaged C++, and, we want to integrate it... however, when i DllImport it into C#, the program freezes. So, we're trying to make it managed interface with unmanaged background to save coding...
the functions require char [] and the compiler doesn't like it. If i compile with char *, then when i go to C#, it says sbyte *...
This is very confusing and i hope that you could help!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
It's utterly disturbing to even think that I won't be able to declare objects on stacks in this new game that M$ calls "managed C++". I don't know what you guys think about this, but this is such a feature that I can't live without (not to mention other drawbacks, such as lack of templates etc.)
Chris, I know you are trying to be a good .NETizen lately, but honestly, don't you think that you should also mention this kind of major drawbacks in addition to your usual one-sided praise for new M$ technologies.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
The only time a stack based object will be needed is for RAII types. Since RAII is a language specific idiom you'll not use it with "managed" types, i.e. it won't be shared across language boundaries in the .NET platform. There's nothing disturbing about this.
As for lack of templates... what lack? Templates haven't been removed from C++, and they make no sense for managed types. Even C# will have templates eventually from what I've read.
You're really mixing yourself up by not keeping in mind that "managed" code (or "managed" types) defines a binary component, much like a COM or Corba component, that runs on the .NET VM. As a binary component certain restrictions must exist. Can you create a COM object on the stack or write a COM template type for instance?
William E. Kempf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I've updated the article a little becuase I had 'managed type' stuck in my head when I should have been discussing reference types. You can still declare value types (int, double, enumerations etc) on the stack as you have always done, and you can still use your unmanaged classes and structures in managed C++ as well.
If there is something in particular you don't like about managed types or .NET in general then I would love to hear your opinions. All I seem to hear are people complaining about garbage collection, the size of the redistributable and the speed. Templates are still with us (ATL7 is out, and Nenad promised WTL will work work with VS7 when it's released). As to the others we'll have to wait and see. Still - my focus at the moment is on ASP.NET since I am busting my guts trying to move the site over to .NET to get some speed and stability. Ask anyone who is moving from ASP to ASP.NET and while you may hear grumblings about the amount of work involved in redoing your basic architecture to cater for the new data access and user controls paradigms (especially from me!), the overall story is all good.
But you know - that's just my opinion as a site admin who is sick and tired of VBScript 
cheers, Chris Maunder
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
beta 1 - not sure how many changes there will be in beta2/RTM. Maybe someone at MS can comment.
cheers, Chris Maunder
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi I would like to know the solution for the following problem. I have an interface with a method "dothis" as given below (language is C#).
double doThis(out ArrayList); //C# interface
I would like to implement this interface in MC++, But I don't know the equivalent for the key word "out". Could you please let me know.
Siemens
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am with you on this one and I have another couple of rants.
As far as I can tell so far "managed code" appears to be nothing more than a synonym for "interpreted code". But of course MS spent too much time bashing Sun for Java because it is also interpreted.
Also ATL7 and WTL are nothing more than (second rate) copies of STL.
But like so often in the past I will have to jump on the MS bandwagon and learn these horrid abominations so that I can keep current.
Blah :P
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
"Managed" code means the code is validated at runtime and that memory is managed by a garbage collector and doesn't need to be freed explicitely. C#, MC++ and other .NET languages are not interpreted by the framework - they (like Java) are compiled. Compiled at run-time or pre-compiled before installed, but never interpreted.
And ATL and WTL perform far different roles than STL.
cheers, Chris Maunder
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|