偵錯工具資料模型 C++ 介面
本主題提供如何使用偵錯工具資料模型 C++ 介面擴充和自訂偵錯工具功能的概觀。
偵錯工具資料模型 C++ 主機介面
偵錯工具資料模型主機
偵錯工具資料模型是設計成元件化系統,可以裝載于各種不同的內容中。 一般而言,資料模型裝載于偵錯工具應用程式的內容中。 若要成為資料模型的主機,必須實作一些介面來公開偵錯工具的核心層面:其目標、記憶體空間、評估工具、符號和類型系統等等...雖然這些介面是由任何想要裝載資料模型的應用程式所實作,但核心資料模型以及與資料模型交互操作的任何延伸模組都會使用這些介面。
核心介面集如下:
介面名稱 | 描述 |
---|---|
IDebugHost | 偵錯主機的核心介面。 |
IDebugHostStatus | 允許用戶端查詢主機狀態的介面。 |
IDebugHostCoNtext | 主機內內容的抽象概念 (例如:特定目標、特定進程、特定位址空間等...) |
IDebugHostErrorSink | 呼叫端實作的介面,可從主機和資料模型的特定部分接收錯誤 |
IDebugHostEvaluator / IDebugHostEvaluator2 | 偵錯主機的運算式評估工具。 |
IDebugHostExtensibility | 用來擴充主機或部分功能的介面, (例如運算式評估工具) 。 |
類型系統和符號介面如下:
InterfaceName | 描述 |
---|---|
IDebugHostSymbols | 提供符號存取和解析的核心介面 |
IDebugHostSymbol / IDebugHostSymbol2 | 表示任何種類的單一符號。 特定符號是這個介面的衍生。 |
IDebugHostModule | 表示在進程內載入的模組。 這是一種符號。 |
IDebugHostType / IDebugHostType2 | 表示原生/語言類型。 |
IDebugHostConstant | 表示符號資訊內的常數 (,例如:C++) 中的非類型樣板引數 |
IDebugHostField | 表示結構或類別內的欄位。 |
IDebugHostData | 代表模組內的資料 (在結構或類別中,其會是 IDebugHostField) |
IDebugHostBaseClass | 表示基類。 |
IDebugHostPublic | 代表 PDB 公用資料表內的符號。 這沒有與其相關聯的類型資訊。 它是名稱和位址。 |
IDebugHostModuleSignature | 代表模組簽章 -- 依名稱和/或版本比對一組模組的定義 |
IDebugHostTypeSignature | 代表類型簽章 -- 依模組和/或名稱比對一組類型的定義 |
核心主機介面:IDebugHost
IDebugHost 介面是任何資料模型主機的核心介面。 其定義如下:
DECLARE_INTERFACE_(IDebugHost, IUnknown)
{
STDMETHOD(GetHostDefinedInterface)(_COM_Outptr_ IUnknown** hostUnk) PURE;
STDMETHOD(GetCurrentContext)(_COM_Outptr_ IDebugHostContext** context) PURE;
STDMETHOD(GetDefaultMetadata)(_COM_Outptr_ IKeyStore** defaultMetadataStore) PURE;
}
如果給定主機存在,GetHostDefinedInterface 方法會傳回主機的主要私人介面。 針對 Windows 的偵錯工具,此處傳回的介面是 IDebugClient (轉換成 IUnknown) 。
GetCurrentCoNtext 方法會傳回介面,表示偵錯工具主機的目前狀態。 這的確切意義會保留給主機,但通常包含偵錯主機使用者介面中作用中的會話、進程和位址空間等專案。 傳回的內容物件對呼叫端而言大致不透明,但在對偵錯主機的呼叫之間傳遞是很重要的物件。 例如,呼叫端讀取記憶體時,請務必知道要讀取記憶體的進程和位址空間。 該概念會封裝在從這個方法傳回的內容物件概念中。
GetDefaultMetadata 方法會傳回預設中繼資料存放區,可用於某些作業 (例如:未傳遞明確中繼資料時,字串轉換) 。 這可讓偵錯主機控制呈現某些資料的方式。 例如,預設中繼資料可能包含 PreferredRadix 機碼,允許主機指出是否應該以十進位或十六進位顯示序數,如果未指定則為 。
請注意,必須手動解析預設中繼資料存放區上的屬性值,而且必須傳遞要查詢預設中繼資料的物件。 GetKey 方法應該用來取代 GetKeyValue。
狀態介面:IDebugHostStatus
IDebugHostStatus 介面可讓資料模型或偵錯主機的用戶端查詢偵錯主機狀態的某些層面。 介面定義如下:
DECLARE_INTERFACE_(IDebugHostStatus, IUnknown)
{
STDMETHOD(PollUserInterrupt)(_Out_ bool* interruptRequested) PURE;
}
PollUserInterrupt 方法可用來查詢偵錯主機的使用者是否要求中斷目前的作業。 例如,資料模型中的屬性存取子可能會呼叫任意程式碼 (例如:JavaScript 方法) 。 該程式碼可能需要任意的時間。 為了讓偵錯主機保持回應,任何可能需要任意時間的程式碼,都應該透過呼叫此方法來檢查中斷要求。 如果 interruptRequested 值傳回為 true,則呼叫端應該立即中止並傳回E_ABORT的結果。
內容介面:IDebugHostCoNtext
內容是資料模型和基礎偵錯主機最重要的層面之一。 當您保存物件時,請務必知道物件來自何處,也就是該物件位於哪個進程、與其相關聯的位址空間。 瞭解這項資訊可正確解譯指標值之類的專案。 IDebugHostCoNtext 類型的物件必須傳遞至偵錯主機上的許多方法。 您可以透過數種方式來取得此介面:
- 藉由取得偵錯工具的目前內容:呼叫 IDebugHost 的 GetCurrentCoNtext 方法
- 藉由取得物件的內容:呼叫 IModelObject 的 GetCoNtext 方法
- 藉由取得符號的內容:呼叫 IDebugHostSymbol 的 GetCoNtext 方法
此外,IDebugHostCoNtext 介面的內容中有兩個值具有特殊意義,這些介面是從資料模型傳回或傳遞至資料模型或偵錯主機方法:
nullptr:表示沒有內容。 某些物件完全有效,沒有內容。 資料模型根命名空間中的 Debugger 物件不會參考特定進程或位址空間內的任何專案。 它沒有內容。
USE_CURRENT_HOST_CONTEXT:sentinel 值,指出應該使用偵錯主機目前的 UI 內容。 這個值永遠不會從偵錯主機傳回。 不過,它可能會傳遞至任何接受輸入 IDebugHostCoNtext 的偵錯主機方法,而不是明確呼叫 IDebugHost 的 GetCurrentCoNtext 方法。 請注意,明確傳遞USE_CURRENT_HOST_CONTEXT通常比明確取得目前內容更具效能。
主機內容的內容對呼叫端而言大致不透明。 核心偵錯主機外部呼叫端可以使用主機內容執行的唯一作業,就是將其與另一個主機內容進行比較。
IDebugHostCoNtext 介面的定義如下:
DECLARE_INTERFACE_(IDebugHostContext, IUnknown)
{
STDMETHOD(IsEqualTo)(_In_ IDebugHostContext *pContext, _Out_ bool *pIsEqual) PURE;
}
IsEqualTo 方法會將主機內容與另一個主機內容進行比較。 如果兩個內容相等,則會傳回這一點的指示。 請注意,此比較不是介面等價。 這會比較內容本身的基礎不透明內容。
錯誤接收:IDebugHostErrorSink
IDebugHostErrorSink 是一種方法,用戶端可以接收在特定作業期間發生的錯誤通知,並視需要路由傳送這些錯誤。 介面定義如下:
enum ErrorClass
{
ErrorClassWarning,
ErrorClassError
}
DECLARE_INTERFACE_(IDebugHostErrorSink, IUnknown)
{
STDMETHOD(ReportError)(_In_ ErrorClass errClass, _In_ HRESULT hrError, _In_ PCWSTR message) PURE;
}
ReportError 方法是錯誤接收的回呼,通知錯誤已發生,並允許接收將錯誤路由傳送至任何適當的 UI 或機制。
主機評估工具:IDebugHostEvaluator / IDebugHostEvaluator2
偵錯主機提供給用戶端的最重要功能片段之一,就是存取其語言型運算式評估工具。 IDebugHostEvaluator 和 IDebugHostEvaluator2 介面是從偵錯主機存取該功能的方法。
介面的定義如下:
DECLARE_INTERFACE_(IDebugHostEvaluator2, IDebugHostEvaluator)
{
//
// IDebugHostEvaluator:
//
STDMETHOD(EvaluateExpression)(_In_ IDebugHostContext* context, _In_ PCWSTR expression, _In_opt_ IModelObject* bindingContext, _COM_Errorptr_ IModelObject** result, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EvaluateExtendedExpression)(_In_ IDebugHostContext* context, _In_ PCWSTR expression, _In_opt_ IModelObject* bindingContext, _COM_Errorptr_ IModelObject** result, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
//
// IDebugHostEvaluator2:
//
STDMETHOD(AssignTo)(_In_ IModelObject* assignmentReference, _In_ IModelObject* assignmentValue, _COM_Errorptr_ IModelObject** assignmentResult, _COM_Outptr_opt_result_maybenull_ IKeyStore** assignmentMetadata) PURE;
}
EvaluateExpression 方法可讓偵錯主機評估語言 (例如:C++) 運算式,並傳回該運算式評估方塊為 IModelObject 的結果值。 這個方法的特定變體只允許語言建構。 在語言中不存在的偵錯主機運算式評估工具中呈現的任何額外功能 (,例如:) 的 LINQ 查詢方法會關閉以供評估使用。
EvaluateExtendedExpression 方法類似于 EvaluateExpression 方法,不同之處在于它會開啟特定偵錯主機選擇新增至運算式評估工具的其他非語言功能。 例如,針對 Windows 的偵錯工具,這可啟用匿名型別、LINQ 查詢、模組限定詞、格式規範和其他非 C/C++ 功能。
IDebugHostEvaluator2
AssignTo 方法會根據所偵錯語言的語意來執行指派。
主機擴充性介面:IDebugHostExtensibility
偵錯主機的某些功能會選擇性地受限於擴充性。 例如,這可能包括運算式評估工具。 IDebugHostExtensibility 介面是存取這些擴充點的方法。 介面定義如下:
DECLARE_INTERFACE_(IDebugHostExtensibility, IUnknown)
{
STDMETHOD(CreateFunctionAlias)(_In_ PCWSTR aliasName, _In_ IModelObject *functionObject) PURE;
STDMETHOD(DestroyFunctionAlias)(_In_ PCWSTR aliasName) PURE;
}
CreateFunctionAlias 方法會為某些延伸模組中實作的方法建立「函式別名」、「快速別名」。 此別名的意義是主機特定。 它可能會使用 函式來擴充主機的運算式評估工具,或者可能會執行完全不同的動作。
DestroyFunctionAlias 方法會復原先前呼叫 CreateFunctionAlias 方法。 函式將不再在快速別名名稱下使用。
存取資料模型
首先,資料模型擴充性 API 的設計訴求是應用程式 (通常是偵錯工具) 做為資料模型的主機。 理論上,任何應用程式都可以藉由提供一組主機 API 來裝載資料模型,這些 API 會將應用程式的偵錯目標型別系統公開 () ,並將一組投影物件公開到資料模型的命名空間中,以瞭解目標、進程、執行緒等...位於這些偵錯目標 (s) 中。
雖然資料模型 API -- 開頭為 IDataModel、IDebugHost和 IModelObject 的 offshoot ,但設計成可攜式,但不會定義「偵錯工具延伸模組」是什麼。 目前,想要擴充適用于 Windows 的偵錯工具及其提供的引擎,必須撰寫引擎擴充功能,才能存取資料模型。 該引擎延伸模組只需要是引擎延伸模組,就如同擴充功能的載入和啟動載入機制一樣。 因此,最小的實作會提供:
- DebugExtensionInitialize:利用已建立的 IDebugClient 來存取資料模型並設定物件模型操作的方法。
- DebugExtensionUninitialize:可復原在 DebugExtensionInitialize 中執行之物件模型操作的方法。
- DebugExtensionCanUnload:傳回延伸模組是否可以卸載的方法。 如果延伸模組中仍有即時 COM 物件,它必須指出這一點。 這是偵錯工具的對等 COM DllCanUnloadNow。 如果這會傳回無法卸載的S_FALSE指示,偵錯工具稍後可以查詢此作業,以查看卸載是否安全,或者它可能會再次呼叫 DebugExtensionInitialize 來重新初始化擴充功能。 延伸模組必須準備好處理這兩個路徑。
- DebugExtensionUnload:在 DLL 卸載之前執行任何最終清除所需的方法
Bridge 介面:IHostDataModelAccess
如前所述,呼叫 DebugExtensionInitialize 時,它會建立偵錯用戶端並取得資料模型的存取權。 這類存取是由舊版 IDebug* 介面的 Windows 偵錯工具與資料模型之間的橋接器介面所提供。 此橋接器介面是 'IHostDataModelAccess,且定義為下列內容:
DECLARE_INTERFACE_(IHostDataModelAccess, IUnknown)
{
STDMETHOD(GetDataModel)(_COM_Outptr_ IDataModelManager** manager, _COM_Outptr_ IDebugHost** host) PURE;
}
GetDataModel 方法是橋接器介面上的 方法,可存取資料模型的兩端:偵錯主機 (偵錯工具的下邊緣) 以傳回的 IDebugHost 介面表示資料模型的主要元件 -- 資料模型管理員是由傳回的 IDataModelManager 介面來表示
偵錯工具資料模型系統介面
資料模型主機
偵錯工具資料模型是設計成元件化系統,可以裝載于各種不同的內容中。 一般而言,資料模型裝載于偵錯工具應用程式的內容中。 為了成為資料模型的主機,必須實作許多介面來公開偵錯工具的核心層面:其目標、記憶體空間、評估工具、符號和類型系統等等...雖然這些介面是由任何想要裝載資料模型的應用程式所實作,但核心資料模型以及與資料模型交互操作的任何延伸模組都會取用這些介面。
類型系統和符號介面如下:
介面名稱 | 描述 |
---|---|
IDebugHostSymbols | 核心介面,可提供符號的存取和解析 |
IDebugHostSymbol / IDebugHostSymbol2 | 表示任何種類的單一符號。 特定符號是這個介面的衍生。 |
IDebugHostModule | 表示在進程內載入的模組。 這是一種符號。 |
IDebugHostType / IDebugHostType2 | 表示原生/語言類型。 |
IDebugHostConstant | 表示符號資訊內的常數 (,例如:C++) 中的非類型樣板引數 |
IDebugHostField | 表示結構或類別內的欄位。 |
IDebugHostData | 表示模組內的資料 (在結構或類別內,它是 IDebugHostField) |
IDebugHostBaseClass | 表示基類。 |
IDebugHostPublic | 表示 PDB 公用資料表內的符號。 這沒有與其相關聯的類型資訊。 它是名稱和位址。 |
IDebugHostModuleSignature | 代表模組簽章 -- 會依名稱和/或版本比對一組模組的定義 |
IDebugHostTypeSignature | 代表類型簽章 -- 定義,其會依模組和/或名稱比對一組類型 |
其他核心介面如下:
介面名稱 | 描述 |
---|---|
IDebugHost | 偵錯主機的核心介面。 |
IDebugHostStatus | 允許用戶端查詢主機狀態的介面。 |
IDebugHostCoNtext | 主機內內容的抽象概念 (例如:特定目標、特定進程、特定位址空間等...) |
IDebugHostErrorSink | 呼叫端實作的介面,可從主機和資料模型的特定部分接收錯誤 |
IDebugHostEvaluator / IDebugHostEvaluator2 | 偵錯主機的運算式評估工具。 |
IDebugHostExtensibility | 用來擴充主機或部分功能的介面, (例如運算式評估工具) 。 |
主要符號介面:IDebugHostSymbols
IDebugHostSymbols 介面是存取偵錯目標中符號的主要起點。 您可以從 IDebugHost 實例查詢此介面,並定義如下:
DECLARE_INTERFACE_(IDebugHostSymbols, IUnknown)
{
STDMETHOD(CreateModuleSignature)(_In_z_ PCWSTR pwszModuleName, _In_opt_z_ PCWSTR pwszMinVersion, _In_opt_z_ PCWSTR pwszMaxVersion, _Out_ IDebugHostModuleSignature** ppModuleSignature) PURE;
STDMETHOD(CreateTypeSignature)(_In_z_ PCWSTR signatureSpecification, _In_opt_ IDebugHostModule* module, _Out_ IDebugHostTypeSignature** typeSignature) PURE;
STDMETHOD(CreateTypeSignatureForModuleRange)(_In_z_ PCWSTR signatureSpecification, _In_z_ PCWSTR moduleName, _In_opt_z_ PCWSTR minVersion, _In_opt_z_ PCWSTR maxVersion, _Out_ IDebugHostTypeSignature** typeSignature) PURE;
STDMETHOD(EnumerateModules)(_In_ IDebugHostContext* context, _COM_Outptr_ IDebugHostSymbolEnumerator** moduleEnum) PURE;
STDMETHOD(FindModuleByName)(_In_ IDebugHostContext* context, _In_z_ PCWSTR moduleName, _COM_Outptr_ IDebugHostModule **module) PURE;
STDMETHOD(FindModuleByLocation)(_In_ IDebugHostContext* context, _In_ Location moduleLocation, _COM_Outptr_ IDebugHostModule **module) PURE;
STDMETHOD(GetMostDerivedObject)(_In_opt_ IDebugHostContext *pContext, _In_ Location location, _In_ IDebugHostType* objectType, _Out_ Location* derivedLocation, _Out_ IDebugHostType** derivedType) PURE;
}
CreateModuleSignature 方法會建立簽章,可用來依名稱和選擇性地依版本比對一組特定模組。 模組簽章有三個元件:
- 名稱:比對模組的名稱必須與簽章中的名稱不區分大小寫
- 最低版本:如果指定,比對的模組必須具有最低版本,且版本至少與這個版本相同。 版本會以 「A.B.C.D」 格式指定,且每個後續部分的重要性低於先前部分。 只有第一個區段是必要的。
- 最大版本:如果指定,比對的模組必須具有高於此版本的最大版本。 版本會以 「A.B.C.D」 格式指定,且每個後續部分的重要性低於先前部分。 只有第一個區段是必要的。
CreateTypeSignature 方法會建立簽章,這個簽章可用來比對一組具體類型,方法是包含模組和類型名稱。 類型名稱簽章字串的格式專屬於正在偵錯的語言 (和偵錯主機) 。 針對 C/C++,簽章字串相當於 NatVis 類型規格。 也就是說,簽章字串是類型名稱,其中範本引數 (指定為 *) 的萬用字元。
CreateTypeSignatureForModuleRange
CreateTypeSignatureForModuleRange 方法會建立簽章,可用來依模組簽章和類型名稱比對一組具體類型。 這類似于 CreateTypeSignature 方法,不同之處在于,呼叫端會傳遞建立模組簽章所需的引數, (如同使用 CreateModuleSignature 方法建立模組簽章) 。
EnumerateModules 方法會建立列舉值,以列舉特定主機內容中可用的每個模組。 該主機內容可能會封裝進程內容,或封裝類似 Windows 核心的內容。
FindModuleByName 方法會查看指定的主機內容,並找出具有指定名稱的模組,並將介面傳回給它。 使用或不使用副檔名來依名稱搜尋模組是合法的。
FindModuleByLocation 方法會查看指定的主機內容,並判斷哪個模組包含指定位置所指定的位址。 接著,它會將介面傳回至這類別模組。
GetMostDerivedObject 會使用偵錯工具的型別系統,從其靜態類型判斷物件的執行時間類型。 這個方法只會使用類型系統層提供的符號資訊和啟發學習法,才能執行這項分析。 這類資訊可能包括 C++ RTTI (執行時間類型資訊,) 或分析物件的虛擬函式資料表圖形。 它不包含 IModelObject 上慣用的執行時間類型概念等專案。 如果分析找不到執行時間類型,或找不到與傳遞至 方法的靜態類型不同的執行時間類型,則可能會傳遞輸入位置和類型。方法不會因為這些原因而失敗。
核心個別符號介面:IDebugHostSymbol
可從資料模型主機傳回的每個符號,都會以某種方式從 IDebugHostSymbol 衍生。 這是每個符號實作的核心介面,不論符號類型為何。 根據符號類型而定,指定的符號可能會實作一組其他介面,這些介面會針對這個介面所代表的特定符號類型傳回更獨特的屬性。 IDebugHostSymbol2 / IDebugHostSymbol 介面的定義如下:
DECLARE_INTERFACE_(IDebugHostSymbol2, IDebugHostSymbol)
{
//
// IDebugHostSymbol:
//
STDMETHOD(GetContext)(_COM_Outptr_ IDebugHostContext** context) PURE;
STDMETHOD(EnumerateChildren)(_In_ SymbolKind kind, _In_opt_z_ PCWSTR name, _Out_ IDebugHostSymbolEnumerator **ppEnum) PURE;
STDMETHOD(GetSymbolKind)(_Out_ SymbolKind *kind) PURE;
STDMETHOD(GetName)(_Out_ BSTR* symbolName) PURE;
STDMETHOD(GetType)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetContainingModule)(_Out_ IDebugHostModule **containingModule) PURE;
STDMETHOD(CompareAgainst)(_In_ IDebugHostSymbol *pComparisonSymbol, _In_ ULONG comparisonFlags, _Out_ bool *pMatches) PURE;
//
// IDebugHostSymbol2
//
STDMETHOD(EnumerateChildrenEx)(_In_ SymbolKind kind, _In_opt_z_ PCWSTR name, _In_opt_ SymbolSearchInfo* searchInfo, _Out_ IDebugHostSymbolEnumerator **ppEnum) PURE;
}
請務必注意,這個介面代表許多種類的符號,以 SymbolKind 列舉來描述,其具有如下的值:
Enumarant | 意義 |
---|---|
符號 | 未指定的符號類型 |
SymbolModule | 符號是模組,可以查詢 IDebugHostModule |
SymbolType | 符號是類型,可以查詢 IDebugHostType |
SymbolField | 符號是結構或類別內資料成員 (欄位) ,並可查詢 IDebugHostField |
SymbolConstant | 符號是常數值,可以查詢 IDebugHostConstant |
SymbolData | 符號是非結構或類別成員的資料,而且可查詢 IDebugHostData |
SymbolBaseClass | 符號是基類,可查詢 IDebugHostBaseClass |
SymbolPublic | 符號是模組公用資料表中的專案, (沒有類型資訊) ,而且可查詢 IDebugHostPublic |
SymbolFunction | 符號是函式,可查詢 IDebugHostData |
GetCoNtext 方法會傳回符號有效的內容。 雖然這會代表符號所在的偵錯目標和進程/位址空間之類的專案,但可能不像從其他 (方法擷取的內容一樣特定,例如:從 IModelObject) 。
EnumerateChildren 方法會傳回列舉值,它會列舉指定符號的所有子系。 例如,針對 C++ 類型,基類、欄位、成員函式等都會被視為類型符號的子系。
模組介面:IDebugHostModule
偵錯工具在某些位址空間內載入的模組概念是以資料模型中的兩種不同的方式表示:透過 IDebugHostModule 介面在類型系統層級上。 在這裡,模組是模組的符號和核心屬性,是透過 Debugger.Models.Module 資料模型在資料模型層級投影的介面方法呼叫。 這是模組類型系統 IDebugHostModule 標記法的可延伸封裝。
IDebugHostModule 介面的定義如下 (忽略 IDebugHostSymbol 泛型方法) :
DECLARE_INTERFACE_(IDebugHostModule, IDebugHostSymbol)
{
//
// IDebugHostModule:
//
STDMETHOD(GetImageName)(_In_ bool allowPath, _Out_ BSTR* imageName) PURE;
STDMETHOD(GetBaseLocation)(_Out_ Location* moduleBaseLocation) PURE;
STDMETHOD(GetVersion)(_Out_opt_ ULONG64* fileVersion, _Out_opt_ ULONG64* productVersion) PURE;
STDMETHOD(FindTypeByName)(_In_z_ PCWSTR typeName, _Out_ IDebugHostType** type) PURE;
STDMETHOD(FindSymbolByRVA)(_In_ ULONG64 rva, _Out_ IDebugHostSymbol** symbol) PURE;
STDMETHOD(FindSymbolByName)(_In_z_ PCWSTR symbolName, _Out_ IDebugHostSymbol** symbol) PURE;
}
GetImageName 方法會傳回模組的映射名稱。 根據 allowPath 引數的值,傳回的映射名稱可能會或可能不會包含映射的完整路徑。
GetBaseLocation 方法會將模組的基底負載位址當做位置結構傳回。 模組的傳回位置結構通常會參考虛擬位址。
GetVersion 方法會傳回模組的版本資訊, (假設這類資訊可以順利讀出標頭) 。 如果透過非 nullptr 輸出指標) 要求指定的版本 (,而且無法讀取,則會從方法呼叫傳回適當的錯誤碼。
FindTypeByName 方法會依類型名稱尋找模組內定義的類型,並傳回其類型符號。 這個方法可能會傳回有效的 IDebugHostType,永遠不會透過模組的明確遞迴子系傳回。 偵錯主機可能會允許建立衍生類型 -- 模組本身內從未使用的類型,但衍生自的類型。 例如,如果結構 MyStruct 定義于模組的符號中,但從未使用 MyStruct 類型 ,則 FindTypeByName 方法可能會合法傳回 MyStruct ** 的類型符號,即使該類型名稱從未明確出現在模組的符號中。
FindSymbolByRVA 方法會在模組內的指定相對虛擬位址找到單一相符符號。 如果提供的 RVA (沒有單一符號,例如:有多個相符專案) ,此方法會傳回錯誤。 請注意,這個方法會偏好傳回私用符號,而非 publics 資料表中的符號。
FindSymbolByName 方法會在模組內尋找指定名稱的單一全域符號。 如果沒有符合指定名稱的單一符號,此方法會傳回錯誤。 請注意,這個方法會偏好傳回私用符號,而非 publics 資料表中的符號。
存取類型系統:IDebugHostType2 / IDebugHostType
指定的語言/原生類型是由 IDebugHostType2 或 IDebugHostType 介面所描述。 請注意,這些介面上的某些方法僅適用于特定類型的類型。 指定的類型符號可能會參考下列其中一種類型,如 TypeKind 列舉所述:
類型種類 | 描述 |
---|---|
TypeUDT | 使用者定義型別 (結構、類別、等位等...) 。模型物件,其類型為 TypeUDT 的原生類型具有 ObjectTargetObject 標準標記法,其中類型一律保留在對應的 IModelObject 內。 |
TypePointer | 指標。 模型物件,其類型為 TypePointer 的原生型別具有 ObjectIntrinsic 的正式標記法,其中指標的值會延伸至VT_UI8,並保留為這個 64 位形式的內建資料。 TypePointer 的任何類型符號都有基底類型 (,如 GetBaseType 方法所傳回) 指標所指向的類型。 |
TypeMemberPointer | 類別成員的指標。 模型物件,其類型為 TypeMemberPointer 的原生型別具有標準標記法,其內建 (值與指標值相同) 。 此值的確切意義是編譯器/偵錯主機特定。 |
TypeArray | 陣列。 模型物件,其類型為 TypeArray 的原生類型具有 ObjectTargetObject 標準標記法。 陣列的基底位址是物件的位置 (透過 GetLocation 方法擷取) ,而且一律會保留陣列的類型。 TypeArray 的任何類型符號都有基底類型 (,由 GetBaseType 方法所傳回,) 陣列為數組的類型。 |
TypeFunction | 函數。 |
TypeTypedef | typedef。 具有原生型別的模型物件,其種類為 TypeTypedef,其標準標記法與 typedef 基礎之最終類型的標準標記法相同。 除非使用 IDebugHostType2 的明確 typedef 方法來查詢 typedef 資訊,或有針對 typedef 註冊的明確資料模型,否則這會對物件的終端使用者和類型資訊完全透明。 請注意,GetTypeKind 方法永遠不會傳回 TypeTypedef。 每個方法都會傳回 typedef 所傳回的最終類型。 IDebugHostType2 上有 typedef 特定方法,可用來取得 typedef 特定資訊。 |
TypeEnum | 列舉。 模型物件,其類型為 TypeEnum 的原生型別具有 ObjectIntrinsic 的正式標記法,其中內建函式的值和類型與列舉值相同。 |
TypeIntrinsic | 內部 (基底類型) 。 模型物件,其類型為 TypeIntrinsic 的原生類型具有 ObjectIntrinsic 標準標記法。 類型資訊可能或可能不會保留 -- 特別是基礎類型完全由儲存在 IModelObject 中內建資料的 variant 資料類型 (VT_*) 時 |
整體 IDebugHostType2 / IDebugHostType 介面的定義如下 (排除 IDebugHostSymbol 方法) :
DECLARE_INTERFACE_(IDebugHostType2, IDebugHostType)
{
//
// IDebugHostType:
//
STDMETHOD(GetTypeKind)(_Out_ TypeKind *kind) PURE;
STDMETHOD(GetSize)(_Out_ ULONG64* size) PURE;
STDMETHOD(GetBaseType)(_Out_ IDebugHostType** baseType) PURE;
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
STDMETHOD(GetIntrinsicType)(_Out_opt_ IntrinsicKind *intrinsicKind, _Out_opt_ VARTYPE *carrierType) PURE;
STDMETHOD(GetBitField)(_Out_ ULONG* lsbOfField, _Out_ ULONG* lengthOfField) PURE;
STDMETHOD(GetPointerKind)(_Out_ PointerKind* pointerKind) PURE;
STDMETHOD(GetMemberType)(_Out_ IDebugHostType** memberType) PURE;
STDMETHOD(CreatePointerTo)(_In_ PointerKind kind, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(GetArrayDimensionality)(_Out_ ULONG64* arrayDimensionality) PURE;
STDMETHOD(GetArrayDimensions)(_In_ ULONG64 dimensions, _Out_writes_(dimensions) ArrayDimension *pDimensions) PURE;
STDMETHOD(CreateArrayOf)(_In_ ULONG64 dimensions, _In_reads_(dimensions) ArrayDimension *pDimensions, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(GetFunctionCallingConvention)(_Out_ CallingConventionKind* conventionKind) PURE;
STDMETHOD(GetFunctionReturnType)(_COM_Outptr_ IDebugHostType** returnType) PURE;
STDMETHOD(GetFunctionParameterTypeCount)(_Out_ ULONG64* count) PURE;
STDMETHOD(GetFunctionParameterTypeAt)(_In_ ULONG64 i, _Out_ IDebugHostType** parameterType) PURE;
STDMETHOD(IsGeneric)(_Out_ bool* isGeneric) PURE;
STDMETHOD(GetGenericArgumentCount)(_Out_ ULONG64* argCount) PURE;
STDMETHOD(GetGenericArgumentAt)(_In_ ULONG64 i, _Out_ IDebugHostSymbol** argument) PURE;
//
// IDebugHostType2:
//
STDMETHOD(IsTypedef)(_Out_ bool* isTypedef) PURE;
STDMETHOD(GetTypedefBaseType)(_Out_ IDebugHostType2** baseType) PURE;
STDMETHOD(GetTypedefFinalBaseType)(_Out_ IDebugHostType2** finalBaseType) PURE;
STDMETHOD(GetFunctionVarArgsKind)(_Out_ VarArgsKind* varArgsKind) PURE;
}
IDebugHostType2/IDebugHostType 一般方法
不論從 GetTypeKind 方法傳回何種類型,下列 IDebugHostType 方法都一般適用于任何類型:
STDMETHOD(GetTypeKind)(_Out_ TypeKind *kind) PURE;
STDMETHOD(GetSize)(_Out_ ULONG64* size) PURE;
STDMETHOD(GetBaseType)(_Out_ IDebugHostType** baseType) PURE;
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
GetTypeKind 方法會傳回符號所參考的 (指標、陣列、內建等類型類型...) 。
GetSize 方法會傳回類型的大小 (,就像在 C++) 中已完成 sizeof (類型) 一樣。
如果類型是另一種單一類型的衍生專案, (例如:因為 MyStruct * 衍生自 MyStruct') ,GetBaseType 方法會傳回衍生的基底類型。 針對指標,這會傳回指向的類型。 對於陣列,這會傳回陣列的陣列。 如果類型不是這類衍生型別,則會傳回錯誤。
GetHashCode 方法會傳回類型的 32 位雜湊碼。 除了全域比對 (,例如:與 * 相等的類型簽章,如果主機) 允許,任何符合特定類型簽章的類型實例都必須傳回相同的雜湊碼。 這個方法會與類型簽章搭配使用,以便比對類型簽章與類型實例。
IDebugHostType2/IDebugHostType 內建方法
下列 IDebugHostType 方法專屬於內建類型 (或保存內建資料的類型,例如列舉) :
STDMETHOD(GetIntrinsicType)(_Out_opt_ IntrinsicKind *intrinsicKind, _Out_opt_ VARTYPE *carrierType) PURE;
GetIntrinsicType 方法會傳回類型類型類型種類的相關資訊。 此方法傳回兩個值:
- 內部類型表示整體類型 (例如:整數、不帶正負號、浮點數) ,但不是類型的大小 (例如:8 位、16 位、32 位、64 位)
- 電信業者類型會指出內建種類如何封裝成 VARIANT 結構。 這是VT_* 常數。
這兩個值的組合提供內建函式的完整資訊集。
IDebugHostType2/IDebugHostType Bitfield 方法
下列 IDebugHostType 方法是儲存在 bitfields 中資料的類型專屬。 內建函式內位位置的相關資訊會儲存為資料模型中類型符號的一部分,而不是位置的屬性。
STDMETHOD(GetBitField)(_Out_ ULONG* lsbOfField, _Out_ ULONG* lengthOfField) PURE;
如果資料結構的指定成員是位欄位 (例如:ULONG MyBits:8) ,則欄位的類型資訊會隨附位欄位位置的相關資訊。 GetBitField 方法可用來擷取該資訊。 此方法會在不是位欄位的任何類型上失敗。 這是方法將失敗的唯一原因。 只要呼叫這個方法並查看成功/失敗就足以區分位欄位與非位欄位。 如果指定的類型確實是位欄位,欄位位置是由半開啟集 (lsbOfField + lengthOfField : lsbOfField]所定義
IDebugHostType2/IDebugHostType 指標相關方法
下列 IDebugHostType 方法專屬於指標類型。 以下是 GetTypeKind 傳回 TypePointer 或 TypeMemberPointer'的類型:
STDMETHOD(GetPointerKind)(_Out_ PointerKind* pointerKind) PURE;
STDMETHOD(GetMemberType)(_Out_ IDebugHostType** memberType) PURE;
如果是指標的類型,GetPointerKind 方法會傳回指標的類型。 這是由 PointerKind 列舉所定義。
對於型別類型 TypeMemberPointer) 所指示的指標對成員 (型別,GetMemberType 方法會傳回指標為指標成員的類別。
IDebugHostType2/IDebugHostType 陣列相關方法
陣列是 GetTypeKind 傳回 TypeArray 的類型。 請注意,偵錯主機類型系統所定義的陣列與 C 所使用的單一維度、零索引型、封裝線性一維陣列不同。 C 樣式陣列符合定義,但陣列的整體範圍在 IDebugHostType 中更為廣泛。 偵錯主機中的陣列可以是多維度,而且陣列中的每個維度都是由稱為 ArrayDimensionThis 描述元的描述元所定義,其欄位如下:
欄位 | 意義 |
---|---|
LowerBound | 陣列的基底索引,做為帶正負號的 64 位值。 針對 C 樣式陣列,這一律為零。 它不需要。 陣列的個別維度可以視為從任何 64 位索引開始,甚至是負數。 |
長度 | 陣列維度的長度,做為不帶正負號的 64 位值。 陣列的索引跨越半開啟集 [LowerBound,LowerBound + Length) 。 |
分散 | 定義陣列維度的步幅。 若要在此維度的索引中將一個 (從 N 增加到 N + 1) ,這表示記憶體中要向前移動的位元組數。 針對 C 樣式陣列,這會是陣列的每個元素大小。 它不需要。 元素之間的填補可以表示為大於每個個別元素大小的步幅。 對於多維度陣列,這個值會指出如何向前移動整個維度。 請考慮 M x N 矩陣。 這可能以資料列主要形式描述為兩個維度: |
{ [LowerBound: 0, Length: M, Stride: N \* sizeof(element)], [LowerBound: 0, Length: N, Stride: sizeof(element)]}
或者,也可以以資料行主要形式描述為兩個維度:
{ [LowerBound: 0, Length: M, Stride: sizeof(element)], [LowerBound: 0, Length: N, Stride: M \* sizeof(element)]}
ArrayDimension 概念允許這種彈性程度。
下列 IDebugHostType 方法專屬於陣列類型。
STDMETHOD(GetArrayDimensionality)(\_Out_ ULONG64\* arrayDimensionality) PURE;
STDMETHOD(GetArrayDimensions)(\_In_ ULONG64 dimensions, \_Out_writes_(dimensions) ArrayDimension \*pDimensions) PURE;
GetArrayDimensionality 方法會傳回陣列所編制索引的維度數目。 針對 C 樣式陣列,此處傳回的值一律為 1。
GetArrayDimensions 方法會傳回一組描述元,一個用於陣列的每個維度,如 GetArrayDimensionality 方法所表示。 每個描述元都是 ArrayDimension 結構,描述每個陣列維度的起始索引、長度和向前步幅。 這可讓描述比 C 類型系統中允許的更強大的陣列建構。
針對 C 樣式陣列,此處會傳回單一陣列維度,其值一律為:
- LowerBound = 0
- Length = ARRAYSIZE (陣列)
- Stride = sizeof (elementType)
IDebugHostType2/IDebugHostType 函式相關方法
類型,指出它們是透過一種 TypeFunction 的函式類型,同時支援 IDebugHostType 和 IDebugHostType2 中的下列方法。
//
// IDebugHostType:
//
STDMETHOD(GetFunctionCallingConvention)(_Out_ CallingConventionKind* conventionKind) PURE;
STDMETHOD(GetFunctionReturnType)(_COM_Outptr_ IDebugHostType** returnType) PURE;
STDMETHOD(GetFunctionParameterTypeCount)(_Out_ ULONG64* count) PURE;
STDMETHOD(GetFunctionParameterTypeAt)(_In_ ULONG64 i, _Out_ IDebugHostType** parameterType) PURE;
//
// IDebugHostType2:
//
STDMETHOD(GetFunctionVarArgsKind)(_Out_ VarArgsKind* varArgsKind) PURE;
GetFunctionCallingConvention 方法會傳回函式的呼叫慣例。 這類會以 CallingConventionKind 列舉的成員的形式傳回。
GetFunctionReturnType 方法會傳回函式的傳回型別。
GetFunctionParameterTypeCount 方法會傳回函式採用的引數數目。 請注意,此計數中不會考慮 C/C++ 省略號型變數引數標記。 必須透過 GetFunctionVarArgsKind 方法偵測到這類存在。 這只會在省略號之前包含引數。
GetFunctionParameterTypeAt 方法會將 i 引數的類型傳回函式。
GetFunctionVarArgsKind 方法會傳回指定的函式是否使用變數引數清單,如果是,則會傳回它所利用的變數引數樣式。 這類是由定義如下之 VarArgsKind 列舉的成員所定義:
列舉 | 意義 |
---|---|
VarArgsNone | 函式不會接受任何變數引數。 |
VarArgsCStyle | 函式是 C 樣式 varargs 函式, (returnType (arg1、arg2、...) ) 。函式所報告的引數數目不包含省略號引數。 任何傳遞的變數引數都會在 GetFunctionParameterTypeCount 方法傳回的引數數目之後發生。 |
IDebugHostType2 GetFunctionVarArgsKind
GetFunctionVarArgsKind 方法會傳回指定的函式是否使用變數引數清單,如果是,則會傳回它所利用的變數引數樣式。 這類是由定義如下之 VarArgsKind 列舉的成員所定義:
IDebugHostType2/IDebugHostType Typedef 相關方法
任何屬於 typedef 的類型都會如同類型是 typedef 基礎的最終類型一樣。 這表示 GetTypeKind 之類的方法不會指出類型為 typedef。 同樣地,GetBaseType 不會傳回定義所參考的類型。 相反地,它們會指出它們的行為就像是在 typedef 基礎的最終定義上呼叫一樣。 例如:
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
'PMYSTRUCT 或 PTRMYSTRUCT 的 IDebugHostType 將會報告下列資訊:
- GetTypeKind 方法會傳回 TypePointer。 最終的基礎類型 MYSTRUCT * 確實是指標。
- 'GetBaseType 方法會傳回 MYSTRUCT 的類型。 MYSTRUCT 的基礎類型 * 是 MYSTRUCT。
此處的唯一差異在於 IDebugHostType2 上的 typedef 特定方法的運作方式。 這些方法是:
STDMETHOD(IsTypedef)(_Out_ bool* isTypedef) PURE;
STDMETHOD(GetTypedefBaseType)(_Out_ IDebugHostType2** baseType) PURE;
STDMETHOD(GetTypedefFinalBaseType)(_Out_ IDebugHostType2** finalBaseType) PURE;
在此範例中:
- IsTypedef 方法會針對 PMYSTRUCT 和 PTRMYSTRUCT 傳回 true
- GetTypedefBaseType 方法會針對 PMYSTRUCT 和 PTRMYSTRUCT 的 PMYSTRUCT 傳回 MYSTRUCT *
- GetTypedefFinalBaseType 方法會針對這兩種類型傳回 MYSTRUCT *
IsTypedef 方法是唯一能夠查看類型是否為 typedef 的方法。 GetTypeKind 方法的行為會如同在基礎類型上呼叫一樣。
GetTypedefBaseType 方法會傳回 typedef 的立即定義。 在檔中所述的範例中:
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
這個方法會針對 PMYSTRUCT 傳回 MYSTRUCT 和 PTRMYSTRUCT 的 PMYSTRUCT。
GetTypedefFinalBaseType 方法會傳回 typedef 是定義的最終類型。 如果 typedef 是另一個 typedef 的定義,這會繼續遵循定義鏈結,直到到達不是 typedef 且該類型會傳回的類型為止。 在檔中所述的範例中:
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
此方法會在 PMYSTRUCT 或 PTRMYSTRUCT 上呼叫時傳回 MYSTRUCT * 。
IDebugHostType2/IDebugHostType 類型建立方法
STDMETHOD(CreatePointerTo)(_In_ PointerKind kind, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(CreateArrayOf)(_In_ ULONG64 dimensions, _In_reads_(dimensions) ArrayDimension *pDimensions, _COM_Outptr_ IDebugHostType** newType) PURE;
常數符號值:IDebugHostConstant
對於符號資訊中存在常數值的位置, (其中特定值是一個符號,可能不是常數值) ,IDebugHostConstant 介面表示這類常數的概念。 這通常用於範本引數之類的位置,其中指定的引數通常是類型,但可能是非類型樣板引數 (,例如:常數) 。
IDebugHostConstant 介面的定義如下 (忽略 IDebugHostSymbol 所實作的泛型方法) :
DECLARE_INTERFACE_(IDebugHostConstant, IDebugHostSymbol)
{
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
GetValue 方法會傳回封裝至 VARIANT 的常數值。 請務必注意,IDebugHostSymbol 上的 GetType 方法可能會傳回常數的特定類型符號。 在這種情況下,不保證類型符號所定義的常數值封裝與此處 GetValue 方法所傳回的封裝相同。
資料成員存取:IDebugHostField
IDebugHostField 類別代表一個符號,這是類別、結構、等位或其他類型建構的資料成員。 它不代表免費資料 (,例如:全域資料) 。 介面的定義如下, (忽略 IDebugHostSymbol) 的泛型方法:
DECLARE_INTERFACE_(IDebugHostField, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetOffset)(_Out_ ULONG64* offset) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
GetLocationKind 方法會根據 LocationKind 列舉傳回符號所在的位置類型。 這類列舉可以是下列其中一個值:
列舉 | 意義 |
---|---|
LocationMember | 欄位是類別、結構、等位或其他類型建構的一般資料成員。 它具有相對於包含型別建構之基底位址的位移。 這類基底位址通常以這個指標表示。 欄位的位移可以透過 GetOffset 方法擷取。 GetLocation 和 GetValue 方法將會失敗,此欄位為 LocationMember。 |
LocationStatic | 欄位是靜態的,而且有自己的位址。 GetLocation 方法會傳回抽象位置 (例如:靜態欄位的位址) 。 LocationStatic 欄位的 GetOffset 和 GetValue 方法將會失敗。 |
LocationConstant | 欄位是常數,且具有值。 GetValue 方法會傳回常數的值。 LocationConstant 欄位的 GetOffset 和 GetLocation 方法將會失敗 |
LocationNone | 欄位沒有位置。 它可能已由編譯器優化,或者可能是宣告但從未定義的靜態欄位。 不論這類欄位的出現方式為何,它都沒有實體存在或值。 它只位於符號中。 所有取得方法 (GetOffset、GetLocation 和 GetValue) 都會失敗,此欄位為 LocationNone。 |
對於具有位移的欄位 (例如:位置種類指出 LocationMember) 的欄位,GetOffset 方法會從包含類型的基底位址傳回位移, (此指標) 欄位本身的資料。 這類位移一律會以不帶正負號的 64 位值表示。 如果指定的欄位沒有位置是包含型別基底位址的位移,GetOffset 方法將會失敗。
對於具有位址的欄位,不論特定類型實例 (例如:位置種類指出 LocationStatic) 的欄位,GetLocation 方法會傳回欄位 (位址的抽象位置) 。 如果指定的欄位沒有靜態位置,GetLocation 方法將會失敗。
對於在符號資訊內定義的常數值欄位 (例如:位置種類指出 LocationConstant) 的欄位,GetValue 方法會傳回欄位的常數值。 如果指定的欄位沒有常數值,GetValue 方法將會失敗。
免費資料存取:IDebugHostData
不是另一種類型成員的模組中的資料是由 IDebugHostData 介面表示。 該介面的定義如下 (忽略 IDebugHostSymbol) 的泛型方法:
DECLARE_INTERFACE_(IDebugHostData, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
所有這些方法在語意上都相當於 IDebugHostField 中的對應專案。 唯一的差別在於 GetLocationKind 方法永遠不會傳回 LocationMember 以取得免費資料。
GetLocationKind 方法會根據 LocationKind 列舉傳回符號所在的位置類型。 您可以在 IDebugHostField 的檔中找到此列舉的描述。
對於具有位址的資料,GetLocation 方法會傳回欄位) 的抽象位置 (位址。 如果指定的資料沒有靜態位置,GetLocation 方法將會失敗。
對於 datawhich 在符號資訊內定義的常數值 (例如:位置種類指出 LocationConstant) 的資料,GetValue 方法會傳回欄位的常數值。 如果指定的資料沒有常數值,GetValue 方法將會失敗。
基類:IDebugHostBaseClass
指定型別的繼承階層是透過類型符號的子系來表示。 如果指定的型別從一或多個類型衍生 (繼承) ,則類型符號的類型符號會有一或多個 SymbolBaseClass 子系。 每個 SymbolBaseClass 符號都代表特定類型的立即繼承。 基類的名稱是 SymbolBaseClass 符號的名稱,以及基類的類型符號名稱。 SymbolBaseClass 符號上的 GetType 方法可用來取得基類本身的類型符號。 您可以透過遞迴探索 SymbolBaseClass 子符號來周遊完整繼承階層。 每個基類符號都是以 IDebugHostBaseClass 介面來表示,其定義如下 (忽略 IDebugHostSymbol 的泛型方法) :
DECLARE_INTERFACE_(IDebugHostBaseClass, IDebugHostSymbol)
{
STDMETHOD(GetOffset)(_Out_ ULONG64* offset) PURE;
}
GetOffset 方法會從衍生類別的基底位址傳回基類的位移。 這類位移可能是零,或可能是正負號的 64 位值。
公用符號:IDebugHostPublic
公用符號代表符號檔內公用資料表中的專案。 它們實際上會匯出位址。 沒有與公用符號相關聯的類型資訊-- 只有位址。 除非呼叫端明確要求公用符號,否則偵錯主機會偏好為每個查詢傳回私人符號。 公用符號是由 IDebugHostPublic 介面表示,其定義為下列 (忽略 IDebugHostSymbol 的泛型方法) :
DECLARE_INTERFACE_(IDebugHostPublic, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
}
所有這些方法在語意上都相當於 IDebugHostField 中的對應專案。 唯一的差別在於 GetLocationKind 方法永遠不會傳回這類符號的 LocationMember 或 LocationConstant。
GetLocationKind 方法會根據 LocationKind 列舉傳回符號所在的位置類型。 您可以在 IDebugHostField 的檔中找到此列舉的描述。
對於具有位址的資料,GetLocation 方法會傳回欄位) 的抽象位置 (位址。 如果指定的公用沒有靜態位置,GetLocation 方法將會失敗。
模組簽章和版本比對:IDebugHostModuleSignature
模組簽章代表檢查指定模組是否符合一組有關命名和版本設定的準則的方法。 模組簽章是透過 IDebugHostSymbols 上的 CreateModuleSignature 方法所建立。 它可以比對模組名稱,以及模組的選擇性版本號碼範圍。 建立這類簽章之後,用戶端會收到 IDebugHostModuleSignature 介面,其定義如下:
DECLARE_INTERFACE_(IDebugHostModuleSignature, IUnknown)
{
STDMETHOD(IsMatch)(_In_ IDebugHostModule* pModule, _Out_ bool* isMatch) PURE;
}
IsMatch 方法會將特定模組 (與簽章的 IDebugHostModule 符號) 比較,並將模組名稱和版本與簽章中所指出的名稱和版本範圍進行比較。 指出指定的模組符號是否符合傳回簽章。
類型簽章和類型比對:IDebugHostTypeSignature
類型簽章代表檢查指定的型別實例是否符合類型名稱的一組準則、型別的泛型引數,以及類型所在的模組。 類型簽章是透過 IDebugHostSymbols 上的 CreateTypeSignature 方法建立。 建立這類簽章之後,用戶端會收到 IDebugHostTypeSignature 介面,其定義如下:
DECLARE_INTERFACE_(IDebugHostTypeSignature, IUnknown)
{
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
STDMETHOD(IsMatch)(_In_ IDebugHostType* type, _Out_ bool* isMatch, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
STDMETHOD(CompareAgainst)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ SignatureComparison* result) PURE;
}
GetHashCode 方法會傳回類型簽章的 32 位雜湊碼。 偵錯主機保證類型實例所傳回的雜湊碼與針對類型簽章傳回的雜湊碼之間,有同步處理。 除了全域比對之外,如果類型實例能夠比對類型簽章,兩者都會有相同的 32 位雜湊碼。 這允許在類型實例與向資料模型管理員註冊的一系列類型簽章之間進行初始快速比較和比對。
IsMatch 方法會傳回特定類型實例是否符合類型簽章中指定的準則的指示。 如果這樣做,則會傳回此指示,以及列舉值,指出類型實例的所有特定部分 (為符號,) 符合類型簽章中的萬用字元。
CompareAgainst 方法會將類型簽章與另一個類型簽章進行比較,並傳回兩個簽章的比較方式。 傳回的比較結果是 SignatureComparison 列舉的成員,其定義如下:
列舉 | 意義 |
---|---|
Unrelated | 兩個簽章或類型之間沒有關聯性。 |
不明確 | 一個簽章或類型會模棱兩可地與另一個簽章比較。 針對兩個類型簽章,這表示有可能符合任一簽章的潛在類型實例。 例如,下面顯示的兩個類型簽章模棱兩可。 簽章 1:簽章 2: std::pair<*, int> std::pair<int,*> 因為類型實例 std::pair<int, int> 符合一個相同 (兩者都有一個具體和一個萬用字元比對) 。 |
LessSpecific | 一個簽章或類型比另一個簽章還少。 通常,這表示較不特定的簽章具有萬用字元,其中較特定的簽章具有具體類型。 例如,下面的第一個簽章小於第二個簽章。 簽章 1:簽章 2: std::pair<*, int> std::pair<int, int> 因為它具有萬用字元, * () 第二個具有具體類型 (int) 。 |
MoreSpecific | 一個簽章或類型比另一個更明確。 這通常表示較特定的簽章具有特定類型,其中較不特定的簽章具有萬用字元。 例如,下面的第一個簽章比第二個簽章更具體。 簽章 1:簽章 2: std::pair<int, int> std::pair<*, int> 因為它具有具體類型 (int) ,而第二個具有萬用字元 (* ) 。 |
相同 | 這兩個簽章或類型完全相同。 |
另請參閱
本主題是一系列的一部分,描述可從 C++ 存取的介面、如何使用它們來建置 C++ 型偵錯工具延伸模組,以及如何利用其他資料模型建構 (例如:JavaScript 或 NatVis) 從 C++ 資料模型延伸模組。