1
votes

I've wrote a C++ library that is exposed to my VB.NET application through a C++/CLI wrapper.

I'm worried about objects that I'm shuttling up to the VB.NET application through the wrapper. To use the classes in the library I've written wrappers for them and the wrapper classes contain pointers to an unmanaged instance of the class. In the destructor of the wrapper class I delete the memory that the unmanaged pointer is pointing to.

If the wrapped .NET library passes one of these class instances to the VB.NET application and the VB.NET application uses it and moves on (doesn't save a reference to it); will the .NET garbage collector come around and dispose this class instance causing the unmanaged memory to be deallocated in the destructor of the class? This would cause an error if I had a reference to this same memory that the wrapped class instance pointed to.

If this is the case then I'll just copy all the data in the wrapper to ensure that my wrappers don't share any data with the native portion of the library. If this isn't the case then do I have to call some sort of dispose method on the wrapped class instance in order to destruct the unmanaged object?

2

2 Answers

1
votes

In CLI, you simply have to use the destructor syntax (~MyClass()) and the C++/CLI compiler will create an IDisposable implementation on the class for you.

This "destructor" (it's not really, it just has the syntax of one) will be called when the Dispose method is called in unmanaged code. It's here that you would put the calls you need to make in order to release resources.

If you want to implement a finalizer, then you would use the new destructor syntax (!MyClass()). This should release the same resources that you would in your "destructor".

Finally, in your managed code, you simply would reference the IDisposable implementation and then call Dispose on it, more than likely through the using statement.

0
votes

You are mixing it up a bit. Yes, after the vb.net code stops referencing one of your C++/CLI classes then eventually the finalizer will be called after the object got collected. Note that this is the finalizer, it has nothing to do with dispose. Your C++/CLI object should provide both a destructor (called by Dispose()) and a finalizer.

There is otherwise no danger of memory corruption. The finalizer only gets called when the garbage collector cannot find any live references to the object. Since there is no reference left, there's no way that you can accidentally access the deleted native object. Check this answer for the standard pattern.