In-Context 攔截函式預防措施
基於效能考慮,客戶端開發人員會註冊內容內攔截函式。 不過,因為這些攔截函式會對應到伺服器的位址空間,用戶端和伺服器開發人員必須採取預防措施,以確保事件處理順利進行。
用戶端開發人員的預防措施
用戶端開發人員應該注意下列問題:
- 內容攔截函式不應該使用很多處理器時間,因為攔截函式必須在伺服器應用程式繼續之前傳回。
- 觸發事件之後,在呼叫攔截函式時,與事件相關聯的視窗可能已不存在。 客戶端必須先確認與事件相關聯的視窗仍然存在,再採取與事件相關的任何其他動作。 為了確保視窗仍然存在,用戶端會使用 Microsoft Win32 IsWindow 函式。
- 如果攔截函式定義連結至另一個 DLL 的 DLL,用戶端開發人員必須確保系統載入另一個 DLL。 如果以隱含方式連結 (使用 .def 檔案和匯入),則其他 DLL 必須位於 Windows 目錄或其中一個系統目錄,例如 Windows\System、Windows\System32 或 Windows\SysWOW64。 如果明確連結 (使用 LoadLibrary),則必須在呼叫 LoadLibrary中指定其他 DLL 所在目錄的完整路徑。
- 當包含攔截函式的 DLL 載入至 16 位應用程式時,內容內攔截函式可能會導致堆疊溢位。 之所以發生此問題,是因為16位應用程式會使用不夠大的固定堆疊大小來容納導致呼叫攔截函式的系統函式呼叫鏈結。
伺服器開發人員的預防措施
伺服器開發人員必須注意用戶端應用程式可能會註冊內容內勾點函式。 當伺服器呼叫 NotifyWinEvent時,必須準備好處理 WM_GETOBJECT 和其他 IAccessible 方法。
無效的介面指標
當用戶端在內容攔截函式內呼叫 AccessibleObjectFromEvent 時,IAccessible 介面指標會直接指向伺服器地址空間中的程式代碼。 如果用戶端使用此指標呼叫介面屬性,元件物件模型 (COM) 連結庫不會涉及封送處理(封裝和傳送跨進程界限的介面參數)或取消封送處理(解除封裝已跨進程界限傳送的參數),也不會偵測到物件是否已終結。
如果用戶端呼叫介面屬性給終結的物件,除非伺服器偵測到這種情況,否則無效的介面指標會導致伺服器位址空間中的一般保護錯誤。
為了防止無效的介面指標,伺服器 建立 Proxy 物件 包裝無障礙物件並監視可存取物件的生命週期。 例如,當用戶端呼叫 IAccessible 屬性以取得對象的相關信息時,Proxy 會檢查可存取的物件是否仍然可用,如果是的話,則會將用戶端的要求轉送至可存取的物件。 如果可存取的物件終結,Proxy 會將錯誤傳回給用戶端。