简体   繁体   中英

How to use Marshal.ReleaseComObject with Win32 native functions

I'm playing around with these two native win32 functions:

    [DllImport( "oleacc.dll" )]
    public static extern int AccessibleObjectFromWindow(
            IntPtr hwnd,
            int dwObjectID,
            ref Guid refID,
            ref Accessibility.IAccessible ppvObject );
    [DllImport( "oleacc.dll" )]
    public static extern uint AccessibleChildren(
        Accessibility.IAccessible paccContainer,
        int iChildStart, 
        int cChildren,
        [Out] object[] rgvarChildren,
        out int pcObtained );

And I'm having a hard time figuring out if I should/need to call Marshal.ReleaseComObject on any of the returned objects. I would be thankful is someone could enlighten me on this topic! Here's a sample usage:

    Accessibility.IAccessible test(
        int hWnd,
        string accessName )
    {
        Guid guidCOM = new Guid( 0x618736E0, 0x3C3D, 0x11CF, 0x81, 0xC, 0x0, 0xAA, 0x0, 0x38, 0x9B, 0x71 );
        Accessibility.IAccessible a = null;

        AccessibleObjectFromWindow(
            new IntPtr( hWnd ),
            -4,
            ref guidCOM,
            ref a );
        object[] children = new object[a.accChildCount];
        int z;
        AccessibleChildren( a, 0, children.Length, children, out z );
        foreach ( Accessibility.IAccessible a2 in children )
            try
            {
                if ( a2.get_accName( 0 ) == accessName )
                    return a2;
            }
            catch
            {
            }
        return null;
    }

Marshal.ReleaseComObject is a useful work-around if you really need to get the GC to apply the release immediately, instead of waiting for the GC to run. It is best to not use it unless you really need to, because it has a tendency to take over your code and you have to apply it every where, including places where you have created implicit references.

I suspect that the best method for COM interop in .Net is to write strongly typed wrapper classes around the methods you are using. This way there is no possibility of introducing implicit references, and it will simplify the code and ensure that the interfaces are more easily reachable for the GC. Some of my cow-orkers have reported better memory behaviour by using this methods - the objects are released in a timely fashion as GC runs without leaving any mystery references lying around.

Generally speaking, all COM objects referenced in .Net code are implemented in the form of an RCW object which holds the true COM reference - the call to ReleaseComObject forces the RCW to decrement the reference by a count of one. In this way it is similar to just calling Release on the actual IUnkown instance. Probably in the example you have above, it is not necessary to make the call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM