RCW & reference counting when using COM interop in C#

后端 未结 5 2050
孤独总比滥情好
孤独总比滥情好 2020-12-04 15:46

I have an application that uses Office interop assemblies. I am aware about the \"Runtime Callable Wrapper (RCW)\" managed by the runtime. But I am not very sure how the ref

5条回答
  •  南方客
    南方客 (楼主)
    2020-12-04 16:47

    The accepted solution is valid, but here's some additional background information.

    A RCW contains one or more native COM object interface references internally for its COM object.

    When a RCW releases its underlying COM object, either due to getting garbage collected or due to Marshal.ReleaseComObject() getting called on it, it releases all of its internally held COM object interfaces.

    There are actually many reference counts here - one determining when .NET's RCW should release its underlying COM object interfaces, and then each of those raw COM interfaces has its own reference count as in regular COM.

    Here's code to get raw COM IUnknown interface reference count:

    int getIUnknownReferenceCount(object comobject)
    {
        var iUnknown = Marshal.GetIUnknownForObject(comObject);
        return Marshal.Release(iUnknown);
    }
    

    And you can get the same for the object's other COM interfaces using Marshal.GetComInterfaceForObject().

    In addition to the ways listed in the accepted solution, we can also increase the .NET RCW reference count artificially by calling something like Marshal.GetObjectForIUnknown().

    Here's example code making use of that technique to get a given COM object's RCW reference count:

    int comObjectReferenceCount(object comObject)
    {
        var iUnknown = Marshal.GetIUnknownForObject(comObject);
        Marshal.GetObjectForIUnknown(iUnknown);
        Marshal.Release(iUnknown);
        return Marshal.ReleaseComObject(comObject);
    }
    

提交回复
热议问题