[英]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.