What are the differences between creating an instance of a .NET object in C++ that is managed vs. unmanaged. That is to say, what are the differences between these to statements:
StreamWriter ^stream = gcnew StreamWriter(fileName);
versus
StreamWriter *stream = new StreamWriter(fileName);
My assumption is that if I use gcnew, the memory allocated for StreamWriter will be managed by the garbage collector. Alternatively if I use the pointer(*) and new keyword, I will have to call delete to deallocate the memory.
My real question is: will the garbage collector manage the memory that is being allocated inside of the .NET objects? For instance if a .NET object instantiates another object, and it goes out of scope - will the garbage collector manage that memory even if I use the pointer(*) and new keyword and NOT the gcnew and handle(^).
In C++/CLI, you can't new a .NET object, you'll get something similar to the following error:
error C2750: 'System::Object' : cannot use 'new' on the reference type; use 'gcnew' instead
Usage of new for .NET objects is allowed in the older Managed Extensions for C++ (/clr:oldsyntax compiler flag). "Managed C++" is now deprecated because it is horrible. It has been superceded by C++/CLI, which introduced the ^ and gcnew.
In C++/CLI, you must use gcnew (and ^ handles) for managed types and you must use new (and * pointers) for native types. If you do create objects on the native heap using new, it is your responsibility to destroy them when you are done with them.
Ideally you should use a smart pointer (like std::shared_ptr or std::unique_ptr) to manage the object on the native heap. However, since you can't have a native smart pointer as a field of a ref class, this isn't entirely straightforward. The simplest and most generic approach would probably be to write your own smart pointer wrapper ref class that correctly implements IDisposable.
When you create an object with gcnew it is binded to the garbage collector, and the garbage collector will be responsible for destroying it.
If you use new it won't be binded to the garbage collector, and it will be your responsibility to delete the object.
Just to clarify:
If you have a managed C# object that contains within it an unmanaged object, the garbage collector will not delete the unmanaged object. It will just call the managed object's destructor (if it exists) before it is deleted. You should write your own code in the destructor to delete the unmanaged objects you created.
Related
I am not clear about the usage of keywords gcnew and ref class. usually in C++ when we use keyword new for creating an object that time only the memory for the class allocated in Heap. As per I read about VC++ ref class when we use this token to create class then the memory for the class allocated in Heap before the object creation. is it true? if suppose it is to be true then what is the usage of gcnew. is gcnew does anything with reference count?
What is difference in below Handler creation statements
1)<class Name> ^<handler> = gcnew <class Name>;
2)<class Name> <handler>;
I know the first one allocates the memory in heap for that class. what about Second one, Usually in C++ if I create handler like this then the memory for that class is allocated in the stack, As per I read in C++/CLI programming when I creating a class using the token ref class then the memory for the class allocated in heap. I want to know whether the Second handler creation statement also creates the memory in heap.
According to MSDN, c++/cx private destructors are “only invoked when the reference count reaches zero.”
Thus, would it be safe to say that no other threads can be manipulating an object when its private destructor is invoked?
In a nutshell, yes.
It's possible someone else could still have references to the class if they did things like cast it to a raw pointer without wrapping it in a ComPtr etc. but that's just buggy code that's going to crash sooner or later anyway.
My class looks like this:
(defclass matrix ()
((rows :initarg :rows :initform 2)
(cols :initarg :cols :initform 2)
(matrix :accessor matrix)))
I have a specialisation of the initialize-instance method which creates the object for the matrix slot by calling into a c++ library. I have a matrix-destroy function which will free the memory allocated in c++.
What I want is to be able to get the garbage collector to call matrix-destroy on the matrix slot. Is there an idiomatic way to do this in common lisp?
In order to run a function after the garbage collector has collecte an object, you need to set a finalizer for that object. The Common Lisp standard does not include finalizers, but implementations do provide them. There is a compatibility library called Trivial Garbage that you can use to set them portably.
Setting a finalizer happens by simply calling FINALIZE on the object you want to attach the finalizer to. The finalizer function must not contain any references to the object itself, as that would prevent it from ever being collected. You should also keep in mind that the finalizer may be executed at any time in any thread, so it should be re-entrant and not depend on any specific dynamic environment.
SBCL manual has a short example for finalizers in 7.4 Garbage Collection. You can also see some existing project that uses them, such as cl-sdl2, which uses them to free SDL surfaces, textures and such. See SDL-COLLECT for where the finalizer is set, and CREATE-RGB-SURFACE for an example of where SDL-COLLECT is called from.
Code in C#
string GetValue()
{
//m_IFC is RCW of a native COM object returns Variant marshalled as managed object
object value1 = m_IFC.GetValue();
string valueStr = (string) value1;
return valueStr;
}
The assembly having above code is hosted in COM out-of-proc server which returns the received string from the API to all clients.
Are there any any potential memory leaks here?
From the code you show there is no potential memory leak if m_IFC is indeed a standard runtime callable wrapper. From the MSDN documetation:
The standard wrapper enforces built-in marshaling rules. For example, when a .NET client passes a String type as part of an argument to an unmanaged object, the wrapper converts the string to a BSTR type. Should the COM object return a BSTR to its managed caller, the caller receives a String. Both the client and the server send and receive data that is familiar to them.
All objects shown in your code are managed types and will be garbage collected when all references to it go out of scope. Any unmanaged memory is already handled by the wrapper.
In Java I create some Threads, and they call the same native method like:
public native String go(String str);
In C Language, I have to make an object for each Thread, and the object is only used by each Thread.
Global reference cannot be used because it's shared by all Threads.
I don't want to create the object each time I invoke the JNI method.
How can I implement this?
So you want thread-local Java objects at the JNI side? Just create a ThreadLocal and store it in a global reference.