簡體   English   中英

如何使用Marshal.ReleaseComObject與Win32本機函數

[英]How to use Marshal.ReleaseComObject with Win32 native functions

我正在玩這兩個原生的win32函數:

    [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 );

而且我很難搞清楚我是否應該/需要在任何返回的對象上調用Marshal.ReleaseComObject。 我很感激有人可以開導我這個話題! 這是一個示例用法:

    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是一個非常有用的解決方法,如果你真的需要讓GC立即應用發布,而不是等待GC運行。 除非你真的需要,否則最好不要使用它,因為它傾向於接管你的代碼而你必須在每個地方都應用它,包括你創建隱式引用的地方。

我懷疑.Net中COM互操作的最佳方法是圍繞您正在使用的方法編寫強類型包裝類。 這樣就不可能引入隱式引用,它將簡化代碼並確保GC更容易訪問接口。 我的一些牛人通過使用這種方法報告了更好的記憶行為 - 當GC運行時,對象會及時釋放,而不會留下任何神秘的參考。

一般來說,.Net代碼中引用的所有COM對象都以RCW對象的形式實現,該對象保存真正的COM引用 - 對ReleaseComObject的調用強制RCW將引用減少一個計數。 這樣,它就像在實際的IUnkown實例上調用Release IUnkown 可能在上面的示例中,沒有必要撥打電話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM