tags:

views:

52

answers:

2

I have a C# class that I've made ComVisible so that it can be used in an unmanaged C++ DLL. The C# class is defined like this:

public interface IFSFunction
{
    double GetProcessTime();
}

public class Functions : IFSFunction
{
    // Initialization here

    // Interface function
    public double GetProcessTime()
    {
        // Do stuff - return a value
    }
}

Then, in my C++ DLL I get a reference to the C# class like this:

IFSFunctionPtr pIFuncs;
pIFuncs.CreateInstance(__uuidof(Functions));
double proctime = pIFuncs->GetProcessTime()
pIFuncs.Detach()->Release();

This calls the C# functions very nicely, but it doesn't seem to clean up correctly afterwords. There still seems to be a reference to my C# class hanging around. How can I make sure that my C# COM object is completely gone?

A: 

Does this work for you? (sorry, it's C# rather than C++)

try
{
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(pIFuncs);
}
catch (System.Exception ex)
{
    // Do nothing
}
finally
{
    pIFuncs = null;
}

Info on Marshal.FinalReleaseComObject here.

Cocowalla
I tried calling FinalReleaseComObject(this) in my C# class, but always got an Exception that said: "the object's type must be __ComObject". I don't know how to get around that.
Daedylus
A: 

I'm going to guess you are using a debugging tool that let's you take a look at the managed heap. Like Windbug.exe with sos.dll. Yes, you'll see an instance of the Functions class object after the final Release() call. It is a managed object that follows normal garbage collection rules. It won't be collected until the garbage collector runs. It will be, as long as you keep running managed code that allocates memory.

Hans Passant
Actually, I know that there's still something connected because of a different symptom. Here's the overall setup: Application->C++ DLL->C# COM DLL. My application has a feature that lets me disconnect the C++ DLL so I can recompile it without having to shut down the application. But when I do that, I can recompile the C++ DLL, but not the C# DLL. I get the following message:"The process cannot access the file '..\..\CSFunctions.dll' because it is being used by another process."Is this just because its waiting for the Garbage Collector? Should I ignore this problem?
Daedylus
That's normal. Managed DLLs stay locked and loaded until the AppDomain is unloaded. A direct consequence of JIT compilation. That's not practical to fix since it will be the primary AD. Technically it is possible, you would have to host the CLR yourself and create the AD explicitly. Ignore.
Hans Passant
Thanks. This isn't causing any problems in the behavior of my program, I just wanted to make sure that I was cleaning things up the best I possibly can.
Daedylus