Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused: instance creation of c# class in c++

Assume someClass is a class defined in C# with some method int doSomething(void), and for simplicity, providing a constructor taking no arguments. Then, in C#, instances have to be created on the gc heap:

someClass c;                   // legit, but only a null pointer in C#
// c->doSomething()            // would not even compile. 
c = new someClass();           // now it points to an instance of someclass.
int i = c->doSomething();      

Now, if someClass is compiled into some .Net library, you can also use it in C++/CLI:

someClass^ cpp_gcpointer = gcnew someClass();
int i = cpp_gcpointer->doSomething();

That easy! Nifty! This is of course assuming a reference to the .Net library has been added to the project and a corresponding using declaration has been made.

It is my understanding that this is the precise C++/CLI equivalent of the previous C# example (condensed to a single line, this is not the point I'm interested in). Correct? (Sorry, I'm new to the topic)

In C++, however, also

someClass cpp_cauto;              // in C++ declaration implies instantiation
int i = cpp_cauto.doSomething(); 

is valid syntax. Out of curiosity, I tried this today. A colleague, looking over my shoulder, was willing to bet it would not even compile. He would have lost the bet. (This is still the class from the C# assembly). Actually it produces also the same result i as the code from the previous examples.

Nifty, too, but -- uhmm -- what exactly is it, what is created here? My first wild guess was that behind my back, .Net dynamically creates an instance on the gc heap and cpp_auto is some kind of wrapper for this object, behaving syntactily like an instance of class someClass. But then I found this page

http://msdn.microsoft.com/en-us/library/ms379617%28v=vs.80%29.aspx#vs05cplus_topic2

This page seems to tell me, that (at least, if someClass were a C++ class) cpp_auto is actually created on the stack, which, to my knowledge, would be the same behaviour you get in classical C++. And something you cannot do in C# (you can't, can you?). What I'd like to know: is the instance from the C# assembly also created on the stack? Can you produce .Net binaries in C++ with class instances on the stack which you cannot create in C#? And does this possibly may even give you a perfomance gain :-) ?

Kind regards,

Thomas

like image 839
Thomas Avatar asked Nov 23 '11 19:11

Thomas


1 Answers

The link you referenced explains this in detail:

C++/CLI allows you to employ stack semantics with reference types. What this means is that you can introduce a reference type using the syntax reserved for allocating objects on the stack. The compiler will take care of providing you the semantics that you would expect from C++, and under the covers meet the requirements of the CLR by actually allocating the object on the managed heap.

Basically, it's still making a handle to the reference type on the managed heap, but automatically calls Dispose() on IDisposable implementations when it goes out of scope for you.

The object instance, however, is still effectively allocated via gcnew (placed on the managed heap) and collected by the garbage collector. This, too, is explained in detail:

When d goes out of scope, its Dispose method will be called to allow its resources to be released. Again, since the object is actually allocated from the managed heap, the garbage collector will take care of freeing it in its own time.

Basically, this is all handled by the compiler to make the code look and work like standard C++ stack allocated classes, but its really just a compiler trick. The resulting IL code is still doing managed heap allocations.

like image 92
Reed Copsey Avatar answered Sep 25 '22 11:09

Reed Copsey