다음을 통해 공유


디버거 데이터 모델 C++ 개체

이 항목에서는 디버거 데이터 모델 C++ 개체를 사용하는 방법과 디버거의 기능을 확장하는 방법에 대해 설명합니다.

핵심 디버거 개체 모델

데이터 모델에 대한 가장 기본적이면서도 강력한 것 중 하나는 개체의 정의와 개체와 상호 작용하는 방식을 표준화한다는 것입니다. IModelObject 인터페이스는 해당 개체가 정수, 부동 소수점 값, 문자열, 디버거의 대상 주소 공간에 있는 일부 복합 형식 또는 프로세스 또는 모듈의 개념과 같은 일부 디버거 개념 등 개체의 개념을 캡슐화합니다.

IModelObject에 보관하거나 상자에 넣을 수 있는 여러 가지 사항이 있습니다.

  • 내장 값 - IModelObject8, 16, 32 또는 부호 있거나 부호 없는 64비트 정수, 부울, 문자열, 오류 또는 빈 개념과 같은 다양한 기본 형식에 대한 컨테이너가 될 수 있습니다.

  • 네이티브 개체 - IModelObject디버거가 대상으로 하는 주소 공간 내에서 복잡한 형식(디버거의 형식 시스템에 정의된 대로)을 나타낼 수 있습니다.

  • 가상 개체 - IModelObject동적 개체일 수 있습니다. 즉, 키/값/메타데이터 튜플의 컬렉션과 키/값 쌍으로 표현되지 않는 동작을 정의하는 개념 집합입니다.

  • 속성 - IModelObject메서드 호출을 사용하여 값을 검색하거나 변경할 수 있는 속성을 나타낼 수 있습니다. IModelObject 내의 속성은 사실상 IModelObject박스된 IModelPropertyAccessor 인터페이스입니다.

  • 메서드 - IModelObject인수 집합으로 호출하고 반환 값을 가져올 수 있는 메서드를 나타낼 수 있습니다. IModelObject 내의 메서드는 사실상 IModelObject박스된 IModelMethod 인터페이스입니다.

개체 모델 내 확장성

IModelObject는 격리된 개체가 아닙니다. 위에 표시된 개체 형식 중 하나를 나타내는 것 외에도 각 개체에는 부모 데이터 모델 체인의 개념이 있습니다. 이 체인은 JavaScript 프로토타입 체인처럼 동작합니다. JavaScript와 같은 프로토타입의 선형 체인 대신 각 데이터 모델 개체는 부모 모델의 선형 체인을 정의합니다. 이러한 각 부모 모델에는 자체 부모 집합의 또 다른 선형 체인이 있습니다. 기본적으로 각 개체는 자체 및 이 트리의 모든 개체에 대한 기능(속성 등)의 집계입니다. 특정 속성을 쿼리할 때 쿼리된 개체가 해당 속성을 지원하지 않는 경우 쿼리는 차례로 각 부모에 선형 순서로 전달됩니다. 이렇게 하면 집계 트리의 깊이 우선 검색을 통해 속성 검색이 확인되는 동작이 만들어집니다.

이 개체 모델 내의 확장성은 모든 개체가 자체 및 부모 모델의 트리의 집계라는 개념을 고려할 때 매우 간단합니다. 확장이 들어와서 다른 개체의 부모 모델 목록에 자신을 추가할 수 있습니다. 이렇게 하면 개체가 확장됩니다 . 이러한 방식으로 개체 또는 값의 특정 인스턴스, 네이티브 형식, 프로세스 또는 스레드에 대한 디버거의 개념 또는 "모든 반복 가능한 개체"의 개념 등 모든 기능에 기능을 추가할 수 있습니다.

컨텍스트, 컨텍스트 및 컨텍스트: 이 포인터, 주소 공간 및 구현 프라이빗 데이터

개체 모델의 컨텍스트 내에서 이해해야 하는 세 가지 컨텍스트 개념이 있습니다.

컨텍스트: 이 포인터

지정된 속성 또는 메서드는 데이터 모델 트리의 모든 수준에서 구현될 수 있으므로 메서드 또는 속성의 구현이 원래 개체(C++에서 이 포인터 또는 JavaScript의 이 개체라고 할 수 있음)에 액세스할 수 있어야 합니다. 이 인스턴스 개체는 설명된 메서드에서 컨텍스트라는 첫 번째 인수로 다양한 메서드에 전달됩니다.

컨텍스트: 주소 공간

컨텍스트(대상, 프로세스, 보고 있는 스레드)가 현재 UI 상태를 기준으로 하는 모든 API가 있는 UI 개념인 이전 확장 모델과 달리 데이터 모델 인터페이스는 일반적으로 이 컨텍스트를 명시적으로 또는 암시적으로 IDebugHostContext 인터페이스로 사용합니다. 데이터 모델 내의 각 IModelObject 는 이러한 유형의 컨텍스트 정보를 함께 전달하며 해당 컨텍스트를 반환하는 개체로 전파할 수 있습니다. 즉, IModelObject에서 네이티브 값 또는 키 값을 읽을 때 개체가 원래 가져온 대상 및 프로세스에서 읽습니다.

IDebugHostContext 인수를 사용하는 메서드에 전달할 수 있는 명시적 상수 값(USE_CURRENT_HOST_CONTEXT)이 있습니다. 이 값은 컨텍스트가 실제로 디버거의 현재 UI 상태여야 함을 나타냅니다. 그러나 이 개념은 명시적이어야 합니다.

컨텍스트: 프라이빗 데이터 구현

데이터 모델의 각 개체는 실제로 연결된 부모 모델의 트리와 개체 인스턴스의 집계입니다. 이러한 각 부모 모델(다양한 개체의 체인에 연결될 수 있습니다)은 프라이빗 구현 데이터를 인스턴스 개체와 연결할 수 있습니다. 개념적으로 만들어진 각 IModelObject에는 특정 부모 모델에서 IUnknown 인터페이스로 정의된 프라이빗 인스턴스 데이터로 매핑되는 해시 테이블이 있습니다. 이렇게 하면 부모 모델이 모든 인스턴스에 대한 정보를 캐시하거나 임의 데이터를 연결할 수 있습니다.

이 유형의 컨텍스트는 IModelObject의 GetContextForDataModelSetContextForDataModel 메서드를 통해 액세스됩니다.

핵심 디버거 개체 인터페이스: IModelObject


IModelObject 인터페이스는 다음과 같이 정의됩니다.

DECLARE_INTERFACE_(IModelObject, IUnknown)
{
    STDMETHOD(QueryInterface)(_In_ REFIID iid, _COM_Outptr_ PVOID* iface);
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)() PURE;
    STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
    STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
    STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
    STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
    STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
    STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
    STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
    STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
    STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
    STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
    STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
    STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
    STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
    STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
    STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
    STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
    STDMETHOD(ClearKeys)() PURE;
    STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
    STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
    STDMETHOD(ClearConcepts)() PURE;
    STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
    STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
    STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;
    STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
    STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
}

기본 메서드

다음은 IModelObject가 나타내는 모든 종류의 개체에 적용할 수 있는 일반적인 메서드입니다.

STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;

GetKind

GetKind 메서드는 IModelObject 내에 boxed되는 개체의 종류를 반환합니다.

GetContext

GetContext 메서드는 개체와 연결된 호스트 컨텍스트를 반환합니다.

GetIntrinsicValue

GetIntrinsicValue 메서드는 IModelObject 내부에 상자가 있는 항목을 반환합니다. 이 메서드는 Boxed 내장 함수 또는 boxed인 특정 인터페이스를 나타내는 IModelObject 인터페이스에서만 합법적으로 호출할 수 있습니다. 네이티브 개체, 값 개체, 가상 개체 및 참조 개체에서는 호출할 수 없습니다. GetIntrinsicValueAs 메서드는 값을 지정된 변형 형식으로 변환한다는 점을 제외하고 GetIntrinsicValue 메서드만큼 동작합니다. 변환을 수행할 수 없는 경우 메서드는 오류를 반환합니다.

IsEqualTo

IsEqualTo 메서드는 두 모델 개체를 비교하고 값이 같은지 여부를 반환합니다. 순서가 지정된 개체의 경우 true를 반환하는 이 메서드는 0을 반환하는 Compare 메서드와 동일합니다. 순서가 없지만 동일할 수 있는 개체의 경우 Compare 메서드는 실패하지만 그렇지 않습니다. 값 기반 비교의 의미는 개체 형식에 의해 정의됩니다. 현재는 내장 형식 및 오류 개체에 대해서만 정의됩니다. 동일성을 위한 현재 데이터 모델 개념은 없습니다.

Dereference

Dereference 메서드는 개체를 역참조합니다. 이 메서드는 데이터 모델 기반 참조(ObjectTargetObjectReference, ObjectKeyReference) 또는 네이티브 언어 참조(포인터 또는 언어 참조)를 역참조하는 데 사용할 수 있습니다. 이 메서드는 개체에 대한 단일 수준의 참조 의미 체계를 제거한다는 점에 유의해야 합니다. 예를 들어 언어 참조에 대한 데이터 모델 참조를 사용할 수 있습니다. 이 경우 처음 Dereference 메서드를 호출하면 데이터 모델 참조가 제거되고 언어 참조가 그대로 유지됩니다. 결과 개체에서 역참조를 호출하면 언어 참조가 제거되고 해당 참조 아래에 네이티브 값이 반환됩니다.

키 조작 메서드

키, 값 및 메타데이터 튜플의 사전인 가상 개체에는 이러한 키, 값 및 연결된 메타데이터를 조작하는 일련의 메서드가 있습니다.

API의 값 기반 형식은 다음과 같습니다.

STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
The key based forms of the APIs (including those used for key creation) are: 
STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(ClearKeys)() PURE;

API의 참조 기반 형식은 다음과 같습니다.

STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;

GetKeyValue

GetKeyValue 메서드는 지정된 키의 값(및 연결된 메타데이터)을 이름으로 가져오기 위해 클라이언트가 설정하는 첫 번째 메서드입니다. 키가 속성 접근자인 경우, 즉 박스형 IModelPropertyAccessor인 IModelObject의 값인 경우 GetKeyValue 메서드는 실제 값을 검색하기 위해 속성 접근자의 GetValue 메서드를 자동으로 호출합니다.

SetKeyValue

SetKeyValue 메서드는 키 값을 설정하기 위해 클라이언트가 설정하는 첫 번째 메서드입니다. 이 메서드는 개체에 새 키를 만드는 데 사용할 수 없습니다. 기존 키의 값만 설정합니다. 많은 키가 읽기 전용입니다(예: SetValue 메서드에서 E_NOT_IMPL 반환하는 속성 접근자에 의해 구현됨). 이 메서드는 읽기 전용 키에서 호출될 때 실패합니다.

EnumerateKeyValues

EnumerateKeyValues 메서드는 개체의 모든 키를 열거하기 위해 클라이언트가 설정하는 첫 번째 메서드입니다(부모 모델 트리의 모든 위치에 구현된 모든 키가 포함됨). EnumerateKeyValues는 개체 트리에서 중복 이름으로 정의된 모든 키를 열거합니다. 그러나 GetKeyValue 및 SetKeyValue와 같은 메서드는 깊이 첫 번째 순회에서 검색한 대로 지정된 이름의 키의 첫 번째 인스턴스만 조작합니다.

GetKey

GetKey 메서드는 지정된 키의 값(및 연결된 메타데이터)을 이름으로 가져옵니다. 대부분의 클라이언트는 GetKeyValue 메서드를 대신 활용해야 합니다. 키가 속성 접근자인 경우 이 메서드를 호출하면 IModelObject에 박스된 속성 접근자(IModelPropertyAccessor 인터페이스)가 반환됩니다. GetKeyValue와 달리 이 메서드는 GetValue 메서드를 호출하여 키의 기본 값을 자동으로 해결하지 않습니다. 그 책임은 발신자의 책임입니다.

Setkey

SetKey 메서드는 개체에 키를 만들기 위해 클라이언트에서 설정 하는 메서드 (및 잠재적으로 만든 된 키와 메타 데이터를 연결). 지정된 개체에 지정된 이름의 키가 이미 있는 경우 두 동작 중 하나가 발생합니다. 키가 지정된 인스턴스에 있으면 원래 키가 없는 것처럼 해당 키의 값이 대체됩니다. 반면에 키가 지정된 인스턴스의 부모 데이터 모델 체인에 있는 경우 지정된 이름의 새 키가 지정된 인스턴스에 만들어집니다. 이로 인해 개체에 동일한 이름의 키가 두 개 있습니다(기본 클래스와 같은 이름의 멤버를 숨기도록 하는 파생 클래스와 유사).

EnumerateKeys

EnumerateKeys 메서드는 개체의 속성 접근자를 자동으로 해결하지 않는다는 점을 제외하고 EnumerateKeyValues 메서드와 유사하게 동작합니다. 즉, 키 값이 속성 접근자인 경우 EnumerateKeys 메서드는 GetValue 메서드를 자동으로 호출하지 않고 IModelObject에 박스된 속성 접근자(IModelPropertyAccessorInterface)를 반환합니다. GetKey와 GetKeyValue의 차이점과 비슷합니다.

ClearKeys

ClearKeys 메서드는 지정된 개체의 인스턴스에서 모든 키와 연결된 값 및 메타데이터를 제거합니다. 이 메서드는 특정 개체 인스턴스에 연결된 부모 모델에 영향을 주지 않습니다.

GetKeyReference

GetKeyReference 메서드는 개체(또는 해당 부모 모델 체인)에서 지정된 이름의 키를 검색하고 IModelObject에 박스된 IModelKeyReference 인터페이스에서 제공한 해당 키에 대한 참조를 반환합니다. 이후에 해당 참조를 사용하여 키 값을 얻거나 설정할 수 있습니다.

EnumerateKeyReferences

EnumerateKeyReferences 메서드는 열거하는 키에 대한 참조를 반환한다는 점을 제외하고(IModelObject에 박스된 IModelKeyReference 인터페이스에서 제공됨) 키 값 대신 EnumerateKeyValues 메서드와 유사하게 동작합니다. 이러한 참조를 사용하여 키의 기본 값을 얻거나 설정할 수 있습니다.

개념 조작 메서드

모델 개체가 키/값/메타데이터 튜플의 사전일 뿐만 아니라 개념의 컨테이너이기도 합니다. 개념은 개체에서 또는 개체에서 수행할 수 있는 추상적인 개념입니다. 개념은 기본적으로 개체가 지원하는 인터페이스의 동적 저장소입니다. 현재 데이터 모델에서 정의되는 다양한 개념은 다음과 같습니다.

개념 인터페이스 설명
IDataModelConcept 개념은 부모 모델입니다. 이 모델이 등록된 형식 서명을 통해 네이티브 형식에 자동으로 연결되면 이러한 형식의 새 개체가 인스턴스화될 때마다 InitializeObject 메서드가 자동으로 호출됩니다.
IStringDisplayableConcept 표시를 위해 개체를 문자열로 변환할 수 있습니다.
IIterableConcept 개체는 컨테이너이며 반복할 수 있습니다.
IIndexableConcept 개체는 컨테이너이며 하나 이상의 차원에서 인덱싱(임의 액세스를 통해 액세스)할 수 있습니다.
IPreferredRuntimeTypeConcept 개체는 기본 형식 시스템이 제공할 수 있는 것보다 파생된 형식에 대해 더 잘 알고 있으며 정적 형식에서 런타임 형식으로의 자체 변환을 처리하려고 합니다.
IDynamicKeyProviderConcept 개체는 키의 동적 공급자이며 핵심 데이터 모델의 모든 키 쿼리를 인수하려고 합니다. 이 인터페이스는 일반적으로 JavaScript와 같은 동적 언어에 대한 브리지로 사용됩니다.
IDynamicConceptProviderConcept 개체는 개념의 동적 공급자이며 핵심 데이터 모델의 모든 개념 쿼리를 인수하려고 합니다. 이 인터페이스는 일반적으로 JavaScript와 같은 동적 언어에 대한 브리지로 사용됩니다.

IModelObject의 다음 메서드는 개체가 지원하는 개념을 조작하는 데 사용됩니다.

STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
STDMETHOD(ClearConcepts)() PURE;

GetConcept

GetConcept 메서드는 개체(또는 해당 부모 모델 체인)에서 개념을 검색하고 개념 인터페이스에 대한 인터페이스 포인터를 반환합니다. 개념 인터페이스의 동작 및 메서드는 각 개념에 따라 다릅니다. 그러나 대부분의 개념 인터페이스는 호출자가 컨텍스트 개체(또는 일반적으로 이 포인터를 호출할 수 있는 개체)를 명시적으로 전달해야 한다는 점에 유의해야 합니다. 올바른 컨텍스트 개체가 모든 개념 인터페이스에 전달되도록 하는 것이 중요합니다.

SetConcept

SetConcept 메서드는 이 포인터로 지정된 개체 인스턴스에 지정된 개념을 배치합니다. 이에 의해 지정된 개체 인스턴스에 연결된 부모 모델도 개념을 지원하는 경우 인스턴스의 구현은 부모 모델에서 이를 재정의합니다.

ClearConcepts

ClearConcepts 메서드는 이 메서드로 지정된 개체의 인스턴스에서 모든 개념을 제거합니다.

네이티브 개체 메서드

많은 모델 개체가 내장 함수(예: 정수, 문자열) 또는 가상 구문(키/값/메타데이터 튜플 및 개념 사전)을 참조하는 반면, 모델 개체는 네이티브 구문(예: 디버그 대상의 주소 공간에서 사용자 정의 형식)을 참조할 수도 있습니다. IModelObject 인터페이스에는 이러한 네이티브 개체에 대한 정보에 액세스하는 일련의 메서드가 있습니다. 이러한 메서드는 다음과 같습니다.

STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;

GetRawValue

GetRawValue 메서드는 지정된 개체 내에서 네이티브 구문을 찾습니다. 이러한 구문은 필드, 기본 클래스, 기본 클래스의 필드, 멤버 함수 등이 될 수 있습니다.

EnumerateRawValues

EnumerateRawValues 메서드는 지정된 개체의 모든 네이티브 자식(예: 필드, 기본 클래스 등...)을 열거합니다.

TryCastToRuntimeType

TryCastToRuntimeType 메서드는 디버그 호스트에 분석을 수행하고 지정된 개체의 실제 런타임 형식(예: 대부분의 파생 클래스)을 결정하도록 요청합니다. 사용되는 정확한 분석은 디버그 호스트와 관련이 있으며 RTTI(C++ 런타임 형식 정보), 개체의 V-Table(가상 함수 테이블) 구조 검사 또는 호스트가 정적 형식에서 동적/런타임 형식을 안정적으로 확인하는 데 사용할 수 있는 다른 수단을 포함할 수 있습니다. 런타임 형식으로 변환하지 않는다고 해서 이 메서드 호출이 실패한다는 의미는 아닙니다. 이러한 경우 메서드는 출력 인수에서 지정된 개체(이 포인터)를 반환합니다.

GetLocation

GetLocation 메서드는 네이티브 개체의 위치를 반환합니다. 이러한 위치는 일반적으로 디버그 대상의 주소 공간 내에 있는 가상 주소이지만 반드시 그런 것은 아닙니다. 이 메서드에서 반환되는 위치는 가상 주소일 수 있는 추상 위치이거나, 레지스터 또는 하위 레지스터 내의 배치를 나타내거나, 디버그 호스트에 정의된 다른 임의의 주소 공간을 나타낼 수 있습니다. 결과 Location 개체의 HostDefined 필드가 0이면 위치가 실제로 가상 주소임을 나타냅니다. 이러한 가상 주소는 결과 위치의 오프셋 필드를 검사하여 검색할 수 있습니다. 호스트 정의 필드의 0이 아닌 값은 오프셋 필드가 해당 주소 공간 내의 오프셋인 대체 주소 공간을 나타냅니다. 여기서 0이 아닌 호스트 정의 값의 정확한 의미는 디버그 호스트에 대한 프라이빗입니다.

GetTypeInfo

GetTypeInfo 메서드는 지정된 개체의 네이티브 형식을 반환합니다. 개체에 연결된 네이티브 형식 정보(예: 내장 정보 등)가 없는 경우 호출은 여전히 성공하지만 null을 반환합니다.

GetTargetInfo

GetTargetInfo 메서드는 지정된 개체의 기본 형식뿐만 아니라 추상 위치를 모두 반환하는 GetLocation 및 GetTypeInfo 메서드의 조합입니다.

GetRawReference

GetRawReference 메서드는 지정된 개체 내에서 네이티브 구문을 찾고 해당 개체에 대한 참조를 반환합니다. 이러한 구문은 필드, 기본 클래스, 기본 클래스의 필드, 멤버 함수 등이 될 수 있습니다. 여기서 반환된 참조(ObjectTargetObjectReference 형식의 개체)를 언어 참조(예: C++ 및 &> 스타일 참조)와 구분하는 것이 중요합니다.

EnumerateRawReferences

EnumerateRawReferences 메서드는 지정된 개체의 모든 네이티브 자식(예: 필드, 기본 클래스 등...)에 대한 참조를 열거합니다.

확장성 메서드

앞에서 설명한 대로 모델 개체는 JavaScript 개체 및 프로토타입 체인과 매우 유사하게 동작합니다. 지정된 IModelObject 인터페이스로 표현되는 인스턴스 외에도 개체에 연결된 임의의 수의 부모 모델이 있을 수 있습니다(각각에 임의 수의 부모 모델이 연결될 수 있음). 이는 데이터 모델 내에서 확장성을 위한 기본 수단입니다. 지정된 속성 또는 개념을 지정된 인스턴스 내에 배치할 수 없는 경우 인스턴스에서 루팅된 개체 트리(부모 모델에 의해 정의됨)의 깊이 우선 검색이 수행됩니다.

다음 메서드는 지정된 IModelObject 인스턴스와 연결된 부모 모델의 체인을 조작합니다.

STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;

GetNumberOfParentModels

GetNumberOfParentModels 메서드는 지정된 개체 인스턴스에 연결된 부모 모델의 수를 반환합니다. 부모 모델은 부모 모델 체인의 선형 순서에서 속성 깊이를 먼저 검색합니다.

GetParentModel

GetParentModel 메서드는 지정된 개체의 부모 모델 체인에서 i-th 부모 모델을 반환합니다. 부모 모델은 추가되거나 열거된 선형 순서로 속성 또는 개념을 검색합니다. 인덱스 i가 0인 부모 모델은 인덱스 i + 1이 있는 부모 모델 앞에서(계층적으로) 검색됩니다.

AddParentModel

AddParentModel 메서드는 지정된 개체에 새 부모 모델을 추가합니다. 이러한 모델은 검색 체인의 끝부분에 추가될 수 있습니다(재정의 인수는 false로 지정됨) 또는 검색 체인의 맨 앞에 추가될 수 있습니다(재정의 인수는 true로 지정됨). 또한 각 부모 모델은 지정된 부모(또는 부모 계층 구조의 모든 사용자)의 속성 또는 개념에 대한 컨텍스트(이 포인터 의미 체계)를 선택적으로 조정할 수 있습니다. 컨텍스트 조정은 거의 사용되지 않지만 개체 포함, 네임스페이스 생성 등과 같은 몇 가지 강력한 개념을 허용합니다.

RemoveParentModel

RemoveParentModel은 지정된 개체의 부모 검색 체인에서 지정된 부모 모델을 제거합니다.

SetContextForDataModel

SetContextForDataModel 메서드는 데이터 모델 구현에서 구현 데이터를 인스턴스 개체에 배치하는 데 사용됩니다. 개념적으로 각 IModelObject(단순성을 위해 이 인스턴스를 호출)에는 해시 상태 테이블이 포함되어 있습니다. 해시 테이블은 인스턴스의 부모 모델 계층 구조에 있는 다른 IModelObject(단순성을 위해 데이터 모델 호출)에 의해 인덱싱됩니다. 이 해시에 포함된 값은 IUnknown 인스턴스가 나타내는 참조 계산된 상태 정보 집합입니다. 데이터 모델이 인스턴스에서 이 상태를 설정하면 속성 getter와 같은 작업 중에 검색할 수 있는 임의의 구현 데이터를 저장할 수 있습니다.

GetContextForDataModel

GetContextForDataModel 메서드는 SetContextForDataModel에 대한 이전 호출로 설정된 컨텍스트 정보를 검색하는 데 사용됩니다. 그러면 인스턴스 개체의 부모 모델 계층 구조에서 데이터 모델을 통해 인스턴스 개체에 설정된 상태 정보를 검색합니다. 이 컨텍스트/상태 및 해당 의미에 대한 자세한 내용은 SetContextForDataModel에 대한 설명서를 참조하세요.

디버거 데이터 모델 핵심 개체 형식

데이터 모델의 개체는 .NET의 Object 개념과 비슷합니다. 데이터 모델이 이해하는 구문이 boxed될 수 있는 제네릭 컨테이너입니다. 네이티브 개체와 가상(동적) 개체 외에도 IModelObject의 컨테이너에 배치(또는 boxed)할 수 있는 일련의 핵심 개체 형식이 있습니다. 이러한 값의 대부분이 배치되는 컨테이너는 표준 COM/OLE VARIANT이며 VARIANT에 포함될 수 있는 항목에 대한 여러 가지 추가 제한이 적용됩니다. 가장 기본적인 유형은 다음과 같습니다.

  • 부호 없는 8비트 및 부호 있는 값(VT_UI1, VT_I1)
  • 부호 없는 16비트 및 부호 있는 값(VT_UI2, VT_UI2)
  • 부호 없는 32비트 및 부호 있는 값(VT_UI4, VT_I4)
  • 부호 없는 64비트 및 부호 있는 값(VT_UI8, VT_I8)
  • 단정밀도 부동 소수점 값(VT_R4, VT_R8)
  • 문자열(VT_BSTR)
  • 부울(VT_BOOL)

이러한 기본 형식 외에도 저장된 IUnknown이 특정 인터페이스를 구현하도록 보장되는 VT_UNKNOWN 정의된 여러 핵심 데이터 모델 개체가 IModelObject에 배치됩니다. 그 유형은 다음과 같습니다.

  • 속성 접근자(IModelPropertyAccessor)
  • 메서드 개체(IModelMethod)
  • 키 참조 개체(IModelKeyReference 또는 IModelKeyReference2)
  • 컨텍스트 개체(IDebugModelHostContext)

속성 접근자: IModelPropertyAccessor

데이터 모델의 속성 접근자는 IModelObject에 boxed되는 IModelPropertyAccessor 인터페이스의 구현입니다. 모델 개체는 쿼리할 때 일종의 ObjectPropertyAccessor를 반환하고 내장 값은 IModelPropertyAccessor에 대해 쿼리할 수 있도록 보장되는 VT_UNKNOWN. 이 프로세스에서는 IModelPropertyAccessor로 정적으로 캐스팅할 수 있습니다.

속성 접근자가 데이터 모델에서 키 값을 가져오고 설정하기 위한 메서드 호출을 가져오는 간접적인 방법입니다. 지정된 키의 값이 속성 접근자인 경우 GetKeyValue 및 SetKeyValue 메서드는 이를 자동으로 확인하고 속성 접근자의 기본 GetValue 또는 SetValue 메서드를 적절하게 호출합니다.

IModelPropertyAccessor 인터페이스는 다음과 같이 정의됩니다.

DECLARE_INTERFACE_(IModelPropertyAccessor, IUnknown)
{
    STDMETHOD(GetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _COM_Outptr_ IModelObject** value) PURE;
    STDMETHOD(SetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _In_ IModelObject* value) PURE; 
}

GetValue

GetValue 메서드는 속성 접근자에 대한 getter입니다. 클라이언트가 속성의 기본 값을 가져오려고 할 때마다 호출됩니다. 속성 접근자를 직접 가져오는 호출자는 키 이름과 정확한 인스턴스 개체(이 포인터)를 속성 접근자의 GetValue 메서드에 전달하는 역할을 합니다.

SetValue

SetValue 메서드는 속성 접근자에 대한 setter입니다. 클라이언트가 기본 속성에 값을 할당하려고 할 때마다 호출됩니다. 많은 속성이 읽기 전용입니다. 이러한 경우 SetValue 메서드를 호출하면 E_NOTIMPL 반환됩니다. 속성 접근자를 직접 가져오는 호출자는 키 이름과 정확한 인스턴스 개체(이 포인터)를 속성 접근자의 SetValue 메서드에 전달하는 작업을 담당합니다.

메서드: IModelMethod

데이터 모델의 메서드는 IModelObject에 boxed되는 IModelMethod 인터페이스의 구현입니다. 모델 개체는 쿼리할 때 일종의 ObjectMethod를 반환하고 내장 값은 IModelMethod에 대해 쿼리할 수 있도록 보장되는 VT_UNKNOWN. 이 프로세스에서는 IModelMethod로 정적으로 캐스팅할 수 있습니다. 데이터 모델의 모든 메서드는 본질적으로 동적입니다. 0개 이상의 인수 집합을 입력으로 사용하고 단일 출력 값을 반환합니다. 오버로드 확인 및 매개 변수 이름, 형식 또는 기대에 대한 메타데이터가 없습니다.

IModelMethod 인터페이스는 다음과 같이 정의됩니다.

DECLARE_INTERFACE_(IModelMethod, IUnknown)
{
    STDMETHOD(Call)(_In_opt_ IModelObject *pContextObject, _In_ ULONG64 argCount, _In_reads_(argCount) IModelObject **ppArguments, _COM_Errorptr_ IModelObject **ppResult, _COM_Outptr_opt_result_maybenull_ IKeyStore **ppMetadata) PURE;
}

Call

호출 메서드는 데이터 모델에 정의된 모든 메서드가 호출되는 방식입니다. 호출자는 정확한 인스턴스 개체(이 포인터) 및 임의의 인수 집합을 전달합니다. 메서드의 결과 및 해당 결과와 연결된 선택적 메타데이터가 반환됩니다. 값을 논리적으로 반환하지 않는 메서드는 유효한 IModelObject를 반환해야 합니다. 이 경우 IModelObject는 상자가 없는 값입니다. 메서드가 실패하는 경우 반환된 HRESULT가 실패하더라도 입력 인수에 선택적 확장 오류 정보를 반환할 수 있습니다. 호출자가 이를 위해 검사 것이 중요합니다.

키 참조: IModelKeyReference 또는 IModelKeyReference2

키 참조는 기본적으로 특정 개체의 키에 대한 핸들입니다. 클라이언트는 GetKeyReference와 같은 메서드를 통해 이러한 핸들을 검색하고 나중에 핸들을 사용하여 원래 개체를 반드시 유지하지 않고 키 값을 가져오거나 설정할 수 있습니다. 이 형식의 개체는 IModelObject에 boxed되는 IModelKeyReference 또는 IModelKeyReference2 인터페이스의 구현입니다. 모델 개체는 쿼리할 때 일종의 ObjectKeyReference를 반환하고 내장 값은 IModelKeyReference에 대해 쿼리할 수 있도록 보장되는 VT_UNKNOWN. 이 프로세스에서는 IModelKeyReference로 정적으로 캐스팅할 수 있습니다.

키 참조 인터페이스는 다음과 같이 정의됩니다.

DECLARE_INTERFACE_(IModelKeyReference2, IModelKeyReference)
{
    STDMETHOD(GetKeyName)(_Out_ BSTR* keyName) PURE;
    STDMETHOD(GetOriginalObject)(_COM_Outptr_ IModelObject** originalObject) PURE;
    STDMETHOD(GetContextObject)(_COM_Outptr_ IModelObject** containingObject) PURE;
    STDMETHOD(GetKey)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(GetKeyValue)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetKey)(_In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
    STDMETHOD(SetKeyValue)(_In_ IModelObject* object) PURE;
    STDMETHOD(OverrideContextObject)(_In_ IModelObject* newContextObject) PURE;
}

GetKeyName

GetKeyName 메서드는 이 키 참조가 핸들인 키의 이름을 반환합니다. 반환된 문자열은 표준 BSTR이며 SysFreeString 호출을 통해 해제되어야 합니다.

GetOriginalObject

GetOriginalObject 메서드는 키 참조가 만들어진 인스턴스 개체를 반환합니다. 키 자체는 인스턴스 개체의 부모 모델에 있을 수 있습니다.

GetContextObject

GetContextObject 메서드는 해당 키가 속성 접근자를 참조하는 경우 속성 접근자의 GetValue 또는 SetValue 메서드에 전달되는 컨텍스트(이 포인터)를 반환합니다. 여기서 반환된 컨텍스트 개체는 GetOriginalObject에서 가져온 원래 개체와 같거나 다를 수 있습니다. 키가 부모 모델에 있고 해당 부모 모델과 연결된 컨텍스트 조정자가 있는 경우 원래 개체는 GetKeyReference 또는 EnumerateKeyReferences가 호출된 인스턴스 개체입니다. 컨텍스트 개체는 원래 개체와 이 키 참조가 핸들인 키를 포함하는 부모 모델 간의 최종 컨텍스트 조정기에서 나오는 항목입니다. 컨텍스트 조정자가 없으면 원래 개체와 컨텍스트 개체가 동일합니다.

GetKey

키 참조의 GetKey 메서드는 IModelObject의 GetKey 메서드처럼 동작합니다. 기본 키의 값과 키와 연결된 메타데이터를 반환합니다. 키 값이 속성 접근자가 되는 경우 IModelObject에 박스된 속성 접근자(IModelPropertyAccessor)를 반환합니다. 이 메서드는 속성 접근자에서 기본 GetValue 또는 SetValue 메서드를 호출하지 않습니다.

GetKeyValue

키 참조의 GetKeyValue 메서드는 IModelObject의 GetKeyValue 메서드처럼 동작합니다. 기본 키의 값과 키와 연결된 메타데이터를 반환합니다. 키 값이 속성 접근자가 되는 경우 속성 접근자에서 기본 GetValue 메서드를 자동으로 호출합니다.

Setkey

키 참조의 SetKey 메서드는 IModelObject의 SetKey 메서드처럼 동작합니다. 키 값을 할당합니다. 원래 키가 속성 접근자인 경우 속성 접근자가 바뀝니다. 속성 접근자에서 SetValue 메서드를 호출하지 않습니다.

SetKeyValue

키 참조의 SetKeyValue 메서드는 IModelObject의 SetKeyValue 메서드처럼 동작합니다. 키 값을 할당합니다. 원래 키가 속성 접근자인 경우 속성 접근자 자체를 바꾸는 대신 속성 접근자에서 기본 SetValue 메서드를 호출합니다.

OverrideContextObject

OverrideContextObject 메서드(IModelKeyReference2에만 있음)는 이 키 참조가 기본 속성 접근자의 GetValue 또는 SetValue 메서드에 전달할 컨텍스트 개체를 영구적으로 변경하는 데 사용되는 고급 메서드입니다. 이 메서드에 전달된 개체도 GetContextObject 호출에서 반환됩니다. 이 메서드는 스크립트 공급자가 특정 동적 언어 동작을 복제본(replica) 데 사용할 수 있습니다. 대부분의 클라이언트는 이 메서드를 호출해서는 안 됩니다.

컨텍스트 개체: IDebugHostContext

컨텍스트 개체는 디버그 호스트(데이터 모델과 협력)가 모든 개체와 연결하는 정보의 불투명 Blob입니다. 여기에는 정보가 제공되는 프로세스 컨텍스트 또는 주소 공간 등과 같은 항목이 포함될 수 있습니다. 컨텍스트 개체는 IModelObject 내에 박스된 IDebugHostContext의 구현입니다. IDebugHostContext는 호스트 정의 인터페이스입니다. 클라이언트는 이 인터페이스를 구현하지 않습니다.

컨텍스트 개체 에 대한 자세한 내용은 디버거 데이터 모델 C++ 인터페이스 의 디버거 데이터 모델 C++ 호스트 인터페이스를 참조하세요.

데이터 모델 관리자

데이터 모델 관리자 IDataModelManager2(또는 이전 IDataModelManager)에 대한 핵심 인터페이스는 다음과 같이 정의됩니다.

DECLARE_INTERFACE_(IDataModelManager2, IDataModelManager)
{
    //
    // IDataModelManager:
    //
    STDMETHOD(Close)() PURE;
    STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
    STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
    STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
    STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
    STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
    STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
    STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
    STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
    STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
    STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;
    //
    // IDataModelManager2:
    //
    STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;
    STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
}

관리 방법

다음 메서드 집합은 데이터 모델을 호스팅하는 애플리케이션(예: 디버거)에서 사용됩니다.

STDMETHOD(Close)() PURE;

닫기

Close 메서드는 데이터 모델 관리자의 종료 프로세스를 시작하기 위해 데이터 모델을 호스트하는 애플리케이션(예: 디버거)에 의해 데이터 모델 관리자에서 호출됩니다. 데이터 모델 관리자에 대한 최종 참조를 릴리스하기 전에 Close 메서드를 사용하지 않는 데이터 모델의 호스트는 데이터 모델에 대한 관리 인프라의 상당한 누출을 포함하되 이에 국한되지 않는 정의되지 않은 동작을 일으킬 수 있습니다.

개체 만들기/Boxing 메서드

다음 메서드 집합은 새 개체를 만들거나 데이터 모델의 핵심 인터페이스인 IModelObject에 값을 입력하는 데 사용됩니다.

STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;

CreateNoValue

CreateNoValue 메서드는 "no value" 개체를 만들고 IModelObject에 상자를 만들고 반환합니다. 반환된 모델 개체에는 일종의 ObjectNoValue가 있습니다.

"no value" 개체에는 다음과 같은 몇 가지 의미 체계 의미가 있습니다.

  • (언어에 따라) void, null 또는 undefined에 해당하는 의미 체계로 간주될 수 있습니다.
  • 성공 및 결과 "값 없음" 개체를 반환하는 속성 접근자의 GetValue 메서드는 특정 속성에 지정된 인스턴스에 대한 값이 없으며 해당 특정 인스턴스에 대한 속성이 없는 것처럼 처리되어야 함을 나타냅니다.
  • 의미상 반환 값이 없는 데이터 모델 메서드는 이를 센티넬로 사용하여 이를 나타냅니다(메서드는 유효한 IModelObject를 반환해야 함).

CreateErrorObject

CreateErrorObject 메서드는 "오류 개체"를 만듭니다. 데이터 모델에는 예외 및 예외 흐름의 개념이 없습니다. 다음과 같은 두 가지 방법으로 속성/메서드에서 오류가 발생합니다.

  • 확장 오류 정보가 없는 단일 실패한 HRESULT입니다. 오류에 대해 더 이상 지정할 수 있는 정보가 없거나 오류 자체가 반환된 HRESULT에서 자체 설명입니다.
  • 실패한 단일 HRESULT와 확장된 오류 정보가 결합됩니다. 확장 오류 정보는 속성/메서드의 출력 인수에 반환된 오류 개체입니다.

CreateTypedObject

CreateTypedObject 메서드는 클라이언트가 디버그 대상의 주소 공간에서 네이티브/언어 개체의 표현을 만들 수 있도록 하는 메서드입니다. 새로 만든 개체의 형식(objectType 인수로 표시됨)이 정식 시각화 도우미 또는 확장으로 데이터 모델 관리자에 등록된 하나 이상의 형식 서명과 일치하는 경우 일치하는 데이터 모델은 호출자에게 반환되기 전에 생성된 인스턴스 개체에 자동으로 연결됩니다.

CreateTypedObjectReference

CreateTypedObjectReference 메서드는 기본 네이티브/언어 구문에 대한 참조를 만든다는 점을 제외하고 CreateTypedObject 메서드와 의미상 유사합니다. 만든 참조는 일종의 ObjectTargetObjectReference가 있는 개체입니다. 기본 언어가 지원할 수 있으므로 기본 참조가 아닙니다(예: C++ 및 &&&>). C++ 참조에 대한 ObjectTargetObjectReference를 사용할 수 있습니다. IModelObject에서 Dereference 메서드를 사용하여 ObjectTargetObjectReference 종류의 개체를 기본 값으로 변환할 수 있습니다. 적절한 언어로 값에 다시 할당하기 위해 참조를 기본 호스트의 식 계산기로 전달할 수도 있습니다.

CreateSyntheticObject

CreateSyntheticObject 메서드는 키/값/메타데이터 튜플 및 개념의 사전인 빈 데이터 모델 개체를 만듭니다. 생성 당시에는 개체에 대한 키나 개념이 없습니다. 호출자가 활용할 클린 슬레이트입니다.

CreateDataModelObject

CreateDataModelObject 메서드는 데이터 모델인 개체를 만드는 간단한 도우미 래퍼입니다. 즉, 다른 개체에 부모 모델로 연결될 개체입니다. 이러한 모든 개체는 IDataModelConcept를 통해 데이터 모델 개념을 지원해야 합니다. 이 메서드는 명시적 컨텍스트가 없는 새 빈 가상 개체를 만들고, 새로 만든 개체의 데이터 모델 개념 구현으로 통과된 IDataModelConcept를 추가합니다. CreateSyntheticObject 및 SetConcept에 대한 호출을 통해 이와 유사하게 수행할 수 있습니다.

CreateIntrinsicObject

CreateIntrinsicObject 메서드는 내장 값을 IModelObject에 입력하는 메서드입니다. 호출자는 COM VARIANT에 값을 배치하고 이 메서드를 호출합니다. 데이터 모델 관리자는 개체를 나타내는 IModelObject를 반환합니다. 이 메서드는 기본 IUnknown 기반 형식(속성 접근자, 메서드, 컨텍스트 등)에도 사용됩니다. 이러한 경우 objectKind 메서드는 개체가 나타내는 IUnknown 기반 구문의 종류를 나타내고 전달된 변형의 punkVal 필드는 IUnknown 파생 형식입니다. 형식은 프로세스에서 적절한 모델 인터페이스(예: IModelPropertyAccessor, IModelMethod, IDebugHostContext 등)로 정적으로 캐스팅할 수 있어야 합니다. 이 메서드에서 지원하는 VARIANT 형식은 VT_UI1, VT_I1, VT_UI2, VT_I2, VT_UI4, VT_I4, VT_UI8, VT_I8, VT_R4, VT_R8, VT_BOOL, VT_BSTR 및 VT_UNKNOWN(열거형 ModelObjectKind에서 나타내는 특수한 IUnknown 파생 형식 집합의 경우)입니다.

CreateTypedIntrinsicObject

CreateTypedintrinsicObject 메서드는 네이티브/언어 형식을 데이터와 연결하고 boxed 값과 함께 수행할 수 있다는 점을 제외하고 CreateIntrinsicObject 메서드와 유사합니다. 이렇게 하면 데이터 모델이 네이티브 열거형 형식(단순히 VT_UI* 또는 VT_I* 값)과 같은 구문을 나타낼 수 있습니다. 이 메서드를 사용하여 포인터 형식도 만들어집니다. 데이터 모델의 네이티브 포인터는 디버그 대상의 가상 주소 공간에 대한 오프셋을 나타내는 0개의 확장된 64비트 수량입니다. 이 메서드는 VT_UI8 내부에 상자에 포함되며 이 메서드와 네이티브/언어 포인터를 나타내는 형식으로 만들어집니다.

CreateMetadataStore

CreateMetadataStore 메서드는 키 저장소(키/값/메타데이터 튜플의 간소화된 컨테이너)를 만듭니다. 이 컨테이너는 속성 및 기타 다양한 값과 연결할 수 있는 메타데이터를 저장하는 데 사용됩니다. 메타데이터 저장소에는 단일 부모가 있을 수 있습니다(차례로 단일 부모가 있을 수 있음). 지정된 메타데이터 키가 지정된 저장소에 없으면 해당 부모가 검사. 대부분의 메타데이터 저장소에는 부모가 없습니다. 그러나 일반적인 메타데이터를 쉽게 공유하는 방법을 제공합니다.

CreateTypedIntrinsicObjectEx

CreateTypedIntrinsicObjectEx 메서드는 CreateTypedIntrinsicObject 메서드와 의미상 유사합니다. 둘 사이의 유일한 차이점은 이 메서드를 사용하면 호출자가 내장 데이터가 유효한 컨텍스트를 지정할 수 있다는 것입니다. 컨텍스트가 전달되지 않으면 형식 인수에서 상속된 컨텍스트에서 데이터가 유효한 것으로 간주됩니다(CreateTypedIntrinsicObject가 동작하는 방식). 이렇게 하면 형식에서 상속할 수 있는 것보다 더 구체적인 컨텍스트가 필요한 디버그 대상에 형식화된 포인터 값을 만들 수 있습니다.

확장성/등록 방법 다음 메서드 집합은 데이터 모델의 확장성 메커니즘을 관리하므로 클라이언트가 기존 모델을 확장 또는 등록하거나 데이터 모델에 지정된 기준과 일치하는 네이티브 형식에 지정된 부모 모델을 자동으로 연결하도록 요청할 수 있습니다.

    STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
    STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
    STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
    STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
    STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
    STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
    STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
    STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;

GetModelForTypeSignature

GetModelForTypeSignature 메서드는 RegisterModelForTypeSignature 메서드에 대한 이전 호출을 통해 특정 형식 서명에 대해 등록된 데이터 모델을 반환합니다. 이 메서드에서 반환된 데이터 모델은 전달된 형식 서명과 일치하는 모든 형식에 대한 정식 시각화 도우미로 간주됩니다. 정식 시각화 도우미로서 해당 데이터 모델은 형식의 표시를 인수합니다. 표시 엔진은 기본적으로 데이터 모델에서 제공하는 개체의 뷰를 위해 개체의 네이티브/언어 구문을 숨깁니다.

GetModelForType

GetModelForType 메서드는 지정된 형식 인스턴스에 대한 정식 시각화 도우미인 데이터 모델을 반환합니다. 실제로 이 메서드는 RegisterModelForTypeSignature 메서드에 대한 이전 호출로 등록된 가장 일치하는 형식 서명을 찾고 연결된 데이터 모델을 반환합니다.

RegisterModelForTypeSignature

RegisterModelForTypeSignature 메서드는 호출자가 지정된 형식(또는 형식 집합)에 대한 정식 시각화 도우미를 등록하는 데 사용하는 기본 메서드입니다. 정식 시각화 도우미는 사실상 지정된 형식(또는 형식 집합)의 표시를 인수하는 데이터 모델입니다. 모든 디버거 사용자 인터페이스에 표시되는 형식의 네이티브/언어 뷰 대신 등록된 데이터 모델에서 제시한 형식의 뷰가 표시됩니다(원하는 사용자의 기본/언어 보기로 돌아가는 수단과 함께).

UnregisterModelForTypeSignature

UnregisterModelForTypeSignature 메서드는 RegisterModelForTypeSignature 메서드에 대한 이전 호출을 실행 취소합니다. 이 메서드는 지정된 데이터 모델을 특정 형식 서명과 일치하는 형식에 대한 정식 시각화 도우미로 제거하거나 해당 데이터 모델이 등록된 모든 형식 서명에 대해 정식 시각화 도우미로 지정된 데이터 모델을 제거할 수 있습니다.

RegisterExtensionForTypeSignature

RegisterExtensionForTypeSignature 메서드는 하나의 주요 차이점이 있는 RegisterModelForTypeSignature 메서드와 유사합니다. 이 메서드에 전달되는 데이터 모델은 형식에 대한 정식 시각화 도우미가 아니며 해당 형식의 네이티브/언어 뷰 표시를 인수하지 않습니다. 이 메서드에 전달되는 데이터 모델은 제공된 형식 서명과 일치하는 구체적인 형식에 부모로 자동으로 추가됩니다. RegisterModelForTypeSignature 메서드와 달리 지정된 형식(또는 형식 집합)에 대한 확장으로 등록되는 동일하거나 모호한 형식 서명에는 제한이 없습니다. 형식 서명이 지정된 구체적인 형식 인스턴스와 일치하는 모든 확장은 이 메서드를 통해 등록된 데이터 모델이 새로 만든 개체에 부모 모델로 자동으로 연결되도록 합니다. 이를 통해 임의의 수의 클라이언트가 새 필드 또는 기능으로 형식(또는 형식 집합)을 확장할 수 있습니다.

UnregisterExtensionForTypeSignature

UnregisterExtensionForTypeSignature 메서드는 RegisterExtensionForTypeSignature에 대한 이전 호출을 실행 취소합니다. 특정 데이터 모델을 특정 형식 서명의 확장으로 등록 취소하거나 데이터 모델이 등록된 모든 형식 서명의 확장으로 등록을 취소합니다.

GetRootNamespace

GetRootNamespace 메서드는 데이터 모델의 루트 네임스페이스를 반환합니다. 데이터 모델이 관리하고 디버그 호스트가 특정 개체를 배치하는 개체입니다.

RegisterNamedModel

RegisterNamedModel 메서드는 지정된 데이터 모델을 확장하려는 클라이언트가 찾을 수 있도록 잘 알려진 이름으로 등록합니다. 이 API의 주요 목적은 이 잘 알려진 이름으로 등록된 모델을 검색하고 부모 모델을 추가하여 확장할 수 있는 데이터 모델을 게시하는 것입니다.

UnregisterNamedModel

UnregisterNamedModel 메서드는 RegisterNamedModel에 대한 이전 호출을 실행 취소합니다. 데이터 모델과 조회할 수 있는 이름 간의 연결을 제거합니다.

AcquireNamedModel

지정된 이름으로 등록된 데이터 모델을 확장하려는 호출자는 확장하려는 데이터 모델의 개체를 검색하기 위해 AcquireNamedModel 메서드를 호출합니다. 이 메서드는 RegisterNamedModel 메서드에 대한 이전 호출을 통해 등록된 데이터 모델을 반환합니다. AcquireNamedModel 메서드의 주요 목적은 모델을 확장하는 것이므로 지정된 이름으로 등록된 모델이 아직 없는 경우 이 메서드는 특별한 동작을 가집니다. 지정된 이름 아래에 아직 등록된 모델이 없으면 스텁 개체가 만들어지고, 지정된 이름으로 임시로 등록되고, 호출자에게 반환됩니다. RegisterNamedModel 메서드 호출을 통해 실제 데이터 모델을 등록하는 경우 스텁 개체에 적용된 모든 변경 내용은 실제 모델에 적용됩니다. 이렇게 하면 서로 확장되는 구성 요소에서 많은 부하 순서 종속성 문제가 제거됩니다.

도우미 메서드

다음 메서드는 데이터 모델의 개체에 대해 복잡한 작업을 수행하는 데 도움이 되는 일반적인 도우미 메서드입니다. 데이터 모델 또는 해당 개체에서 다른 메서드를 통해 이러한 작업을 수행할 수 있지만 이러한 편리한 메서드를 사용하면 훨씬 쉽게 수행할 수 있습니다.

STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;

AcquireSubNamespace

AcquireSubNamespace 메서드는 동적 언어의 새 개체보다 일반적으로 언어 네임스페이스처럼 보일 수 있는 항목을 생성하는 데 도움이 됩니다. 예를 들어 호출자가 프로세스 개체의 속성을 분류하여 프로세스 개체를 보다 체계적으로 구성하고 속성을 더 쉽게 검색하려는 경우 이 작업을 수행하는 한 가지 방법은 프로세스 개체의 각 범주에 대한 하위 개체를 만들고 해당 개체 내에 해당 속성을 배치하는 것입니다.

참고 항목

이 항목은 C++에서 액세스할 수 있는 인터페이스, 이를 사용하여 C++ 기반 디버거 확장을 빌드하는 방법 및 C++ 데이터 모델 확장에서 다른 데이터 모델 구문(예: JavaScript 또는 NatVis)을 사용하는 방법을 설명하는 시리즈의 일부입니다.

디버거 데이터 모델 C++ 개요

디버거 데이터 모델 C++ 인터페이스

디버거 데이터 모델 C++ 추가 인터페이스

디버거 데이터 모델 C++ 개념

디버거 데이터 모델 C++ 스크립팅