【c#】使用哪種更好/更安全:HandleRef或IntPtr(Microsoft的更新原始碼不再使用HandleRef)
阿新 • • 發佈:2020-11-23
例如,在舊的.NET Framework 2.0原始碼(Windows窗體,Visual Studio 2005-Whidbey)中,使用 HandleRef 定義了GetClientRect函式:
[DllImport(ExternDll.User32, ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern bool GetClientRect(HandleRef hWnd, [In, Out] ref NativeMethods.RECT rect);
在新的Windows API程式碼包(來自Microsoft,2009/2010)中,使用 IntPtr 定義了相同的功能:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetClientRect(IntPtr hwnd, ref CoreNativeMethods.RECT rect);
實際上, HandleRef 在任何Windows API程式碼包原始檔中均未使用,而在舊.NET Framework原始檔中的本機方法簽名中已大量使用它。
解決辦法
有點腥將控制代碼值儲存在派生自SafeHandle的物件中時,不需要HandleRef。程式碼包聲明瞭ZeroInvalidHandle,並從中派生了幾個類似SafeWindowHandle的程式碼。
但是,它實際上並沒有在任何地方使用任何這些SafeHandle類。不確定是否確實需要,很多Vista和Win7擴充套件實際上是COM介面(interface)。不是傳統的基於控制代碼的C API。它們通過引用計數保持 Activity 狀態,因此不受此類垃圾收集器災難的影響。
就我個人而言,我從來沒有為此擔心。在API呼叫執行期間獲取類物件的收集是一個錯誤。在API呼叫完成後的一微秒內,它很容易發生。仍然是一個錯誤,只有一個錯誤使API呼叫失敗。不確定我是否真的希望它不會失敗,我更希望程式碼中有錯誤時出現異常。微軟需要保護自己免受這種情況的侵害,他們不想為此怪罪。我做。
