How to dispose of a NET COM interop object on Release()
- by mhenry1384
I have a COM object written in managed code (C++/CLI). I am using that object in standard C++.
How do I force my COM object's destructor to be called immediately when the COM object is released? If that's not possible, call I have Release() call a MyDispose() method on my COM object?
My code to declare the object (C++/CLI):
[Guid("57ED5388-blahblah")]
[InterfaceType(ComInterfaceType::InterfaceIsIDispatch)]
[ComVisible(true)]
public interface class IFoo
{
void Doit();
};
[Guid("417E5293-blahblah")]
[ClassInterface(ClassInterfaceType::None)]
[ComVisible(true)]
public ref class Foo : IFoo
{
public:
void MyDispose();
~Foo() {MyDispose();} // This is never called
!Foo() {MyDispose();} // This is called by the garbage collector.
virtual ULONG Release() {MyDispose();} // This is never called
virtual void Doit();
};
My code to use the object (native C++):
#import "..\\Debug\\Foo.tlb"
...
Bar::IFoo setup(__uuidof(Bar::Foo)); // This object comes from the .tlb.
setup.Doit();
setup-Release(); // explicit release, not really necessary since Bar::IFoo's destructor will call Release().
If I put a destructor method on my COM object, it is never called. If I put a finalizer method, it is called when the garbage collector gets around to it. If I explicitly call my Release() override it is never called.
I would really like it so that when my native Bar::IFoo object goes out of scope it automatically calls my .NET object's dispose code. I would think I could do it by overriding the Release(), and if the object count = 0 then call MyDispose(). But apparently I'm not overriding Release() correctly because my Release() method is never called.
Obviously, I can make this happen by putting my MyDispose() method in the interface and requiring the people using my object to call MyDispose() before Release(), but it would be slicker if Release() just cleaned up the object.
Is it possible to force the .NET COM object's destructor, or some other method, to be called immediately when a COM object is released?
Googling on this issue gets me a lot of hits telling me to call System.Runtime.InteropServices.Marshal.ReleaseComObject(), but of course, that's how you tell .NET to release a COM object. I want COM Release() to Dispose of a .NET object.