Natvis 프레임워크를 사용하여 디버거에서 C++ 개체의 사용자 지정 뷰 만들기Create custom views of C++ objects in the debugger using the Natvis framework

Visual Studio Natvis 프레임워크는 네이티브 형식이 디버거 변수 창(예: 지역조사식 창) 및 DataTips에 표시되는 방식을 사용자 지정합니다.The Visual Studio Natvis framework customizes the way native types appear in debugger variable windows, such as the Locals and Watch windows, and in DataTips. Natvis 시각화를 사용하면 디버그하는 동안 만드는 형식을 더 잘 표시할 수 있습니다.Natvis visualizations can help make the types you create more visible during debugging.

Natvis는 이전 버전 Visual Studio의 autoexp.dat 파일을 향상된 진단, 버전 관리 및 다중 파일 지원을 제공하는 XML 구문으로 대체합니다.Natvis replaces the autoexp.dat file in earlier versions of Visual Studio with XML syntax, better diagnostics, versioning, and multiple file support.

참고

Natvis 사용자 지정은 클래스 및 구조체에서 작동하지만 typedef에는 적용되지 않습니다.Natvis customizations work with classes and structs, but not typedefs.

Natvis 시각화Natvis visualizations

만든 형식에 대한 시각화 규칙을 Natvis 프레임워크를 사용하여 만들면 개발자가 디버그 중 형식을 보다 쉽게 확인할 수 있습니다.You use the Natvis framework to create visualization rules for the types you create, so that developers can see them more easily during debugging.

예를 들어 다음 그림에서는 Windows::UI::Xaml::Controls::TextBox 형식의 변수를 사용자 지정 시각화가 적용되지 않은 디버거 창에서 보여 줍니다.For example, the following illustration shows a variable of type Windows::UI::Xaml::Controls::TextBox in a debugger window without any custom visualizations applied.

TextBox 기본 시각화TextBox default visualization

강조 표시된 행은 Text 클래스의 TextBox 속성을 보여 줍니다.The highlighted row shows the Text property of the TextBox class. 복합 클래스 계층 구조를 사용하면 이 속성을 찾기가 어려워집니다.The complex class hierarchy makes it difficult to find this property. 디버거는 사용자 지정 문자열 형식을 해석하는 방법을 인식하지 않으므로 텍스트 상자에 들어 있는 문자열을 볼 수 없습니다.The debugger doesn't know how to interpret the custom string type, so you can't see the string held inside the textbox.

Natvis 사용자 지정 시각화 도우미 규칙이 적용될 때 동일한 TextBox가 변수 창에서 훨씬 더 간단하게 보입니다.The same TextBox looks much simpler in the variable window when Natvis custom visualizer rules are applied. 클래스의 중요한 멤버가 함께 표시되며 디버거에서는 사용자 지정 문자열 형식의 기본 문자열 값을 표시합니다.The important members of the class appear together, and the debugger shows the underlying string value of the custom string type.

시각화 도우미를 사용하는 TextBox 데이터TextBox data using visualizer

C++ 프로젝트에서 .natvis 파일 사용Use .natvis files in C++ projects

Natvis는 .natvis 파일을 사용하여 시각화 규칙을 지정합니다.Natvis uses .natvis files to specify visualization rules. .natvis 파일은 .natvis 확장을 포함하는 XML 파일입니다.A .natvis file is an XML file with a .natvis extension. Natvis 스키마는 %VSINSTALLDIR%\Xml\Schemas\natvis.xsd에 정의됩니다.The Natvis schema is defined in %VSINSTALLDIR%\Xml\Schemas\natvis.xsd.

.natvis 파일의 기본 구조체는 시각화 항목을 나타내는 하나 이상의 Type 요소입니다.The basic structure of a .natvis file is one or more Type elements representing visualization entries. Type 요소의 정규화된 이름은 해당 Name 특성에 지정됩니다.The fully qualified name of each Type element is specified in its Name attribute.

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
  <Type Name="MyNamespace::CFoo">
    .
    .
  </Type>

  <Type Name="...">
    .
    .
  </Type>
</AutoVisualizer>

Visual Studio의 경우 몇 개의 .natvis 파일이 %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers 폴더에 제공됩니다.Visual Studio provides some .natvis files in the %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers folder. 이러한 파일은 많은 공통 형식에 대한 시각화 규칙을 포함하고, 새 형식에 대한 시각화를 작성하기 위한 예제로 활용할 수 있습니다.These files have visualization rules for many common types, and can serve as examples for writing visualizations for new types.

C++ 프로젝트에 .natvis 파일 추가Add a .natvis file to a C++ project

모든 C++ 프로젝트에 .natvis 파일을 추가할 수 있습니다.You can add a .natvis file to any C++ project.

.natvis 파일을 추가하려면To add a new .natvis file:

  1. 솔루션 탐색기에서 C++ 프로젝트 노드를 선택하고 프로젝트 > 새 항목 추가를 선택하거나 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 항목 > 추가를 선택합니다.Select the C++ project node in Solution Explorer, and select Project > Add new item, or right-click the project and select Add > New item.

  2. 새 항목 추가 대화 상자에서 Visual C++ > 유틸리티 > 디버거 시각화 파일(.natvis) 을 선택합니다.In the Add New Item dialog, select Visual C++ > Utility > Debugger visualization file (.natvis).

  3. 파일 이름을 지정하고 추가를 선택합니다.Name the file, and select Add.

    새 파일은 솔루션 탐색기에 추가되고 Visual Studio 문서 창에서 열립니다.The new file is added to Solution Explorer, and opens in the Visual Studio document pane.

Visual Studio 디버거는 C++ 프로젝트에서 .natvis 파일을 자동으로 로드하며, 프로젝트를 빌드할 때에도 기본적으로 이 파일을 .pdb 파일에 포함시킵니다.The Visual Studio debugger loads .natvis files in C++ projects automatically, and by default, also includes them in the .pdb file when the project builds. 빌드된 앱을 디버그하는 경우 디버거는 프로젝트가 열려 있지 않은 경우에도 .pdb 파일에서 .natvis 파일을 로드합니다.If you debug the built app, the debugger loads the .natvis file from the .pdb file, even if you don't have the project open. .natvis 파일이 .pdb에 포함되지 않게 하려면 빌드된 .pdb 파일에서 제외할 수 있습니다.If you don't want the .natvis file included in the .pdb, you can exclude it from the built .pdb file.

.pdb 에서 .natvis 파일을 제외하려면To exclude a .natvis file from a .pdb:

  1. 솔루션 탐색기에서 .natvis 파일을 선택하고 속성 아이콘을 선택하거나 파일을 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.Select the .natvis file in Solution Explorer, and select the Properties icon, or right-click the file and select Properties.

  2. 빌드에서 제외 옆의 화살표를 드롭다운하고 를 선택한 후 확인을 선택합니다.Drop down the arrow next to Excluded From Build and select Yes, and then select OK.

참고

실행 가능 프로젝트를 디버그하는 경우에는 사용할 수 있는 C++ 프로젝트가 없으므로 솔루션 항목을 사용하여 .pdb 파일에 없는 .natvis 파일을 추가합니다.For debugging executable projects, use the solution items to add any .natvis files that are not in the .pdb, since there is no C++ project available.

참고

.pdb에서 로드되는 Natvis 규칙은 .pdb가 참조하는 모듈의 형식에만 적용됩니다.Natvis rules loaded from a .pdb apply only to the types in the modules that the .pdb refers to. 예를 들어 Module1.pdbTest라는 형식에 대한 Natvis 항목이 있는 경우 Module1.dllTest 클래스에만 이 항목이 적용됩니다.For example, if Module1.pdb has a Natvis entry for a type named Test, it only applies to the Test class in Module1.dll. 다른 모듈에도 Test라는 클래스가 정의된 경우 Module1.pdb Natvis 항목은 이 클래스에 적용되지 않습니다.If another module also defines a class named Test, the Module1.pdb Natvis entry does not apply to it.

VSIX 패키지를 통해 .natvis 파일을 설치 및 등록하려면To install and register a .natvis file via a VSIX package:

VSIX 패키지는 .natvis 파일을 설치하고 등록할 수 있습니다.A VSIX package can install and register .natvis files. 설치된 위치에 관계없이 등록된 모든 .natvis 파일은 디버깅 중에 자동으로 선택됩니다.No matter where are they installed, all registered .natvis files are automatically picked up during debugging.

  1. VSIX 패키지에 .natvis 파일을 포함합니다.Include the .natvis file in the VSIX package. 예를 들어 다음 프로젝트 파일의 경우For example, for the following project file:

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
      <ItemGroup>
        <VSIXSourceItem Include="Visualizer.natvis" />
      </ItemGroup>
    </Project>
    
  2. source.extension.vsixmanifest 파일에 .natvis 파일을 등록합니다.Register the .natvis file in the source.extension.vsixmanifest file:

    <?xml version="1.0" encoding="utf-8"?>
    <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
      <Assets>
        <Asset Type="NativeVisualizer" Path="Visualizer.natvis"  />
      </Assets>
    </PackageManifest>
    

Natvis 파일 위치Natvis file locations

.natvis 파일을 여러 프로젝트에 적용하려는 경우에는 사용자 디렉터리 또는 시스템 디렉터리에 해당 파일을 추가합니다.You can add .natvis files to your user directory or to a system directory, if you want them to apply to multiple projects.

.natvis 파일은 다음 순서로 평가됩니다.The .natvis files are evaluated in the following order:

  1. 로드된 프로젝트에 동일한 이름의 파일이 존재하지 않는 경우 디버그하는 .pdb에 포함된 .natvis 모든 파일.Any .natvis files that are embedded in a .pdb you're debugging, unless a file of the same name exists in the loaded project.

  2. 로드된 C++ 프로젝트 또는 최상위 솔루션에 있는 모든 .natvis 파일.Any .natvis files that are in a loaded C++ project or top-level solution. 이 그룹에는 C++ 클래스 라이브러리를 비롯하여 로드된 모든 프로젝트가 포함되지만 다른 언어의 프로젝트는 포함되지 않습니다.This group includes all loaded C++ projects, including class libraries, but not projects in other languages.

  3. VSIX 패키지를 통해 설치 및 등록된 모든 .natvis 파일.Any .natvis files installed and registered via a VSIX package.

  1. 사용자별 natvis 디렉터리(예: %USERPROFILE%\Documents\Visual Studio 2017\Visualizers).The user-specific Natvis directory (for example, %USERPROFILE%\Documents\Visual Studio 2017\Visualizers).
  1. 사용자별 Natvis 디렉터리(예: %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).The user-specific Natvis directory (for example, %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).
  1. 시스템 차원 Natvis 디렉터리( %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers).The system-wide Natvis directory (%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers). 이 디렉터리에는 Visual Studio와 함께 설치되는 .natvis 파일이 있습니다.This directory has the .natvis files that are installed with Visual Studio. 관리자 권한이 있는 경우 이 디렉터리에 파일을 추가할 수 있습니다.If you have administrator permissions, you can add files to this directory.

디버그하는 동안 .natvis 파일 수정Modify .natvis files while debugging

프로젝트를 디버그하는 동안 IDE에서 .natvis 파일을 수정할 수 있습니다.You can modify a .natvis file in the IDE while debugging its project. 디버그 중인 동일한 Visual Studio 인스턴스에서 파일을 열고 수정하고 저장합니다.Open the file in the same instance of Visual Studio you're debugging with, modify it, and save it. 파일이 저장되는 즉시 조사식지역 창이 업데이트되어 변경 내용을 반영합니다.As soon as the file is saved, the Watch and Locals windows update to reflect the change.

디버그 중인 솔루션에서 .natvis 파일을 추가하거나 삭제할 수도 있습니다. 그러면 Visual Studio에서 관련 시각화를 추가하거나 제거합니다.You can also add or delete .natvis files in a solution that you're debugging, and Visual Studio adds or removes the relevant visualizations.

디버그하는 동안 .pdb 파일에 포함된 .natvis 파일을 업데이트할 수는 없습니다.You can't update .natvis files that are embedded in .pdb files while you're debugging.

Visual Studio 외부에서 .natvis 파일을 수정하면 변경 내용이 자동으로 적용되지 않습니다.If you modify the .natvis file outside of Visual Studio, the changes don't take effect automatically. 디버거 창을 업데이트하려면 직접 실행 창에서 .natvisreload 명령을 다시 실행하면 됩니다.To update the debugger windows, you can reevaluate the .natvisreload command in the Immediate window. 그러면 디버깅 세션을 다시 시작하지 않아도 변경 내용이 적용됩니다.Then the changes take effect without restarting the debugging session.

또한 .natvisreload 명령을 사용하여 .natvis 파일을 최신 버전으로 업그레이드할 수 있습니다.Also use the .natvisreload command to upgrade the .natvis file to a newer version. 예를 들어 .natvis 파일이 소스 제어에 체크 인되었는데 다른 사용자가 수행한 최근 변경 내용을 선택하려고 할 수 있습니다.For example, the .natvis file may be checked into source control, and you want to pick up recent changes that somebody else made.

식 및 형식 지정Expressions and formatting

Natvis 시각화에서는 C++ 식을 사용하여 표시할 데이터 항목을 지정합니다.Natvis visualizations use C++ expressions to specify the data items to display. 디버거에서 C++ 식의 기능 향상 및 제한 사항(컨텍스트 연산자(C++)에 설명되어 있음) 외에도 다음 사항에 주의해야 합니다.In addition to the enhancements and limitations of C++ expressions in the debugger, which are described in Context operator (C++), be aware of the following:

  • Natvis 식은 현재 스택 프레임이 아닌 시각화되는 개체의 컨텍스트에서 평가됩니다.Natvis expressions are evaluated in the context of the object being visualized, not the current stack frame. 예를 들어 Natvis 식의 x는 현재 함수의 x라는 지역 변수가 아니라 시각화되는 개체의 x라는 필드를 참조합니다.For example, x in a Natvis expression refers to the field named x in the object being visualized, not to a local variable named x in the current function. Natvis 식 내의 지역 변수에는 액세스할 수 없지만 전역 변수에는 액세스할 수 있습니다.You can't access local variables in Natvis expressions, although you can access global variables.

  • Natvis 식에서는 함수 계산 또는 부작용이 허용되지 않습니다.Natvis expressions don't allow function evaluation or side effects. 함수 호출 및 할당 연산자가 무시됩니다.Function calls and assignment operators are ignored. 디버거 내장 함수 는 부작용이 발생하지 않기 때문에 다른 함수 호출이 금지되어 있더라도 어떤 Natvis 식에서든 자유롭게 호출할 수 있습니다.Because debugger intrinsic functions are side-effect free, they may be freely called from any Natvis expression, even though other function calls are disallowed.

  • 식이 표시되는 방식을 제어하기 위해 C++의 형식 지정자에 설명된 모든 형식 지정자를 사용할 수 있습니다.To control how an expression displays, you can use any of the format specifiers described in Format specifiers in C++. ArrayItems 확장Size 식 같이 항목이 Natvis 내부에서 사용되는 경우에는 형식 지정자가 무시됩니다.Format specifiers are ignored when the entry is used internally by Natvis, such as the Size expression in a ArrayItems expansion.

Natvis 뷰Natvis views

여러 가지 방법으로 형식을 표시하는 다양한 Natvis 뷰를 정의할 수 있습니다.You can define different Natvis views to display types in different ways. 예를 들어 다음은 simple이라는 간단한 뷰를 정의하는 std::vector의 시각화입니다.For example, here is a visualization of std::vector that defines a simplified view named simple. DisplayStringArrayItems 요소는 기본 뷰와 simple 뷰에 표시되는 반면 [size][capacity] 항목은 simple 뷰에 표시되지 않습니다.The DisplayString and the ArrayItems elements show in the default view and the simple view, while the [size] and [capacity] items don't show in the simple view.

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

조사식 창에서는 ,view 형식 지정자를 사용하여 대체 뷰를 지정할 수 있습니다.In the Watch window, use the ,view format specifier to specify an alternate view. 단순 보기는 vec,view(simple) 로 표시됩니다.The simple view appears as vec,view(simple):

단순 보기의 조사식 창Watch window with simple view

Natvis 오류Natvis errors

디버거는 시각화 항목에서 오류를 발견하면 이를 무시하고When the debugger encounters errors in a visualization entry, it ignores them. 형식을 원시 형식으로 표시하거나 다른 적합한 시각화를 선택합니다.It either displays the type in its raw form, or picks another suitable visualization. Natvis 진단을 사용하여 디버거가 시각화 항목을 무시한 이유를 파악하고 기본 구문 및 구문 분석 오류를 확인할 수 있습니다.You can use Natvis diagnostics to understand why the debugger ignored a visualization entry, and to see underlying syntax and parse errors.

Natvis 진단을 켜려면To turn on Natvis diagnostics:

  • 도구 > 옵션(또는 디버그 > 옵션) > 디버깅 > 출력 창에서 Natvis 진단 메시지(C++만 해당)오류, 경고 또는 자세한 정보로 설정하고 확인을 선택합니다.Under Tools > Options (or Debug > Options) > Debugging > Output Window, set Natvis diagnostic messages (C++ only) to Error, Warning, or Verbose, and then select OK.

출력 창에 오류가 표시됩니다.The errors appear in the Output window.

Natvis 구문 참조Natvis syntax reference

AutoVisualizer 요소AutoVisualizer element

AutoVisualizer 요소는 .natvis 파일의 루트 노드이며 네임스페이스 xmlns: 특성을 포함합니다.The AutoVisualizer element is the root node of the .natvis file, and contains the namespace xmlns: attribute.

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer>

AutoVisualizer 요소는 Type, HResult, UIVisualizerCustomVisualizer 자식을 포함할 수 있습니다.The AutoVisualizer element can have Type, HResult, UIVisualizer, and CustomVisualizer children.

Type 요소Type element

기본 Type은 다음과 비슷합니다.A basic Type looks like this example:

<Type Name="[fully qualified type name]">
  <DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
  <Expand>
    ...
  </Expand>
</Type>

Type 요소는 다음을 지정합니다.The Type element specifies:

  1. 시각화가 사용되는 대상 형식(Name 특성)What type the visualization should be used for (the Name attribute).

  2. 이 형식의 개체 값이 표시되는 모양( DisplayString 요소)What the value of an object of that type should look like (the DisplayString element).

  3. 사용자가 변수 창에서 형식을 확장할 경우 형식 멤버가 표시되는 모양(Expand 노드)What the members of the type should look like when the user expands the type in a variable window (the Expand node).

템플릿 기반 클래스Templated classes

Type 요소의 Name 특성은 별표(*)를 템플릿 기반 클래스 이름에 사용할 수 있는 와일드카드 문자로 허용합니다.The Name attribute of the Type element accepts an asterisk * as a wildcard character that can be used for templated class names.

다음 예제에서는 개체가 CAtlArray<int> 또는 CAtlArray<float>인지 관계없이 동일한 시각화가 사용됩니다.In the following example, the same visualization is used whether the object is a CAtlArray<int> or a CAtlArray<float>. CAtlArray<float>에 대한 특정 시각화 항목이 있으면 일반적인 시각화 항목보다 우선 적용됩니다.If there's a specific visualization entry for a CAtlArray<float>, then it takes precedence over the generic one.

<Type Name="ATL::CAtlArray&lt;*&gt;">
    <DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>

매크로 $T1, $T2 등을 사용하여 시각화 항목에서 템플릿 매개 변수를 참조할 수 있습니다.You can reference template parameters in the visualization entry by using macros $T1, $T2, and so forth. 이러한 매크로의 예를 살펴보려면 Visual Studio와 함께 제공되는 .natvis 파일을 참조하세요.To find examples of these macros, see the .natvis files shipped with Visual Studio.

시각화 도우미 형식 일치Visualizer type matching

시각화 항목이 유효성 검사에 실패하면 다음으로 사용 가능한 시각화가 사용됩니다.If a visualization entry fails to validate, the next available visualization is used.

상속 가능한 특성Inheritable attribute

선택적 Inheritable 특성은 시각화가 기본 형식에만 적용되는지 또는 기본 형식 및 모든 파생 형식에 적용되는지 여부를 지정합니다.The optional Inheritable attribute specifies whether a visualization applies only to a base type, or to a base type and all derived types. Inheritable 의 기본값은 true입니다.The default value of Inheritable is true.

다음 예제에서 시각화는 BaseClass 형식에만 적용됩니다.In the following example, the visualization applies only to the BaseClass type:

<Type Name="Namespace::BaseClass" Inheritable="false">
    <DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>

Priority 특성Priority attribute

선택적 Priority 특성은 정의를 구문 분석하지 못하는 경우 대체 정의를 사용하는 순서를 지정합니다.The optional Priority attribute specifies the order in which to use alternate definitions, if a definition fails to parse. Priority의 가능한 값은 Low, MediumLow,Medium, MediumHigh, High입니다.The possible values of Priority are: Low, MediumLow,Medium, MediumHigh, and High. 기본값은 Medium입니다.The default value is Medium. Priority 특성은 동일한 .natvis 파일 내에서의 우선 순위만 구분합니다.The Priority attribute distinguishes only among priorities within the same .natvis file.

다음 예제에서는 먼저 2015 STL과 일치하는 항목을 구문 분석합니다.The following example first parses the entry that matches the 2015 STL. 구문 분석에 실패하는 경우 STL의 2013 버전용 대체 항목을 사용합니다.If that fails to parse, it uses the alternate entry for the 2013 version of the STL:

<!-- VC 2013 -->
<Type Name="std::reference_wrapper&lt;*&gt;" Priority="MediumLow">
     <DisplayString>{_Callee}</DisplayString>
    <Expand>
        <ExpandedItem>_Callee</ExpandedItem>
    </Expand>
</Type>

<!-- VC 2015 -->
<Type Name="std::reference_wrapper&lt;*&gt;">
    <DisplayString>{*_Ptr}</DisplayString>
    <Expand>
        <Item Name="[ptr]">_Ptr</Item>
    </Expand>
</Type>

Optional 특성Optional attribute

모든 노드에 Optional 특성을 넣을 수 있습니다.You can put an Optional attribute on any node. 선택적 노드 내부의 하위 식이 구문 분석에 실패하는 경우 디버거는 해당 노드를 무시하지만 나머지 Type 규칙을 적용합니다.If a subexpression inside an optional node fails to parse, the debugger ignores that node, but applies the rest of the Type rules. 다음 형식에서 [State] 는 필수이지만 [Exception] 은 선택적입니다.In the following type, [State] is non-optional, but [Exception] is optional. MyNamespace::MyClass에 _M_exceptionHolder라는 필드가 있는 경우 [State] 노드와 [Exception] 노드가 모두 표시되지만 _M_exceptionHolder 필드가 없는 경우에는 [State] 노드만 표시됩니다.If MyNamespace::MyClass has a field named _M_exceptionHolder, both the [State] node and the [Exception] node appear, but if there's no _M_exceptionHolder field, only the [State] node appears.

<Type Name="MyNamespace::MyClass">
    <Expand>
      <Item Name="[State]">_M_State</Item>
      <Item Name="[Exception]" Optional="true">_M_exceptionHolder</Item>
    </Expand>
</Type>

조건 특성Condition attribute

선택적 Condition 특성은 많은 시각화 요소에 사용할 수 있으며 시각화 규칙을 사용할 시기를 지정합니다.The optional Condition attribute is available for many visualization elements, and specifies when to use a visualization rule. 조건 특성 내부의 식이 false로 확인되면 시각화 규칙이 적용되지 않습니다.If the expression inside the condition attribute resolves to false, the visualization rule doesn't apply. true로 계산되거나 Condition 특성이 없으면 시각화가 적용됩니다.If it evaluates to true, or there is no Condition attribute, the visualization applies. 시각화 항목에서 if-else 논리에 대해 이 특성을 사용할 수 있습니다.You can use this attribute for if-else logic in the visualization entries.

예를 들어 다음 시각화에는 스마트 포인터 형식에 대해 두 개의 DisplayString 요소가 있습니다.For example, the following visualization has two DisplayString elements for a smart pointer type. _Myptr 멤버가 비어 있으면 첫 번째 DisplayString 요소의 조건이 true로 확인되어 해당 양식이 표시됩니다.When the _Myptr member is empty, the condition of the first DisplayString element resolves to true, so that form displays. _Myptr 멤버가 비어 있지 않으면 조건이 false로 계산되고 두 번째 DisplayString 요소가 표시됩니다.When the _Myptr member is not empty, the condition evaluates to false, and the second DisplayString element displays.

<Type Name="std::auto_ptr&lt;*&gt;">
  <DisplayString Condition="_Myptr == 0">empty</DisplayString>
  <DisplayString>auto_ptr {*_Myptr}</DisplayString>
  <Expand>
    <ExpandedItem>_Myptr</ExpandedItem>
  </Expand>
</Type>

IncludeView 및 ExcludeView 특성IncludeView and ExcludeView attributes

IncludeViewExcludeView 특성은 특정 뷰에 표시되거나 표시되지 않는 요소를 지정합니다.The IncludeView and ExcludeView attributes specify elements to display or not display in specific views. 예를 들어 다음 Natvis 사양 std::vector에서 simple 뷰에 [size][capacity] 항목이 표시되지 않습니다.For example, in the following Natvis specification of std::vector, the simple view doesn't display the [size] and [capacity] items.

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

IncludeViewExcludeView 특성은 개별 멤버 및 형식에 사용할 수 있습니다.You can use the IncludeView and ExcludeView attributes on types and on individual members.

Version 요소Version element

Version 요소는 시각화 항목의 범위를 특정 모듈 및 버전으로 지정합니다.The Version element scopes a visualization entry to a specific module and version. Version 요소를 사용하면 이름 충돌을 방지하고 실수로 인한 불일치를 줄이고 형식 버전마다 다른 시각화를 사용할 수 있습니다.The Version element helps avoid name collisions, reduces inadvertent mismatches, and allows different visualizations for different type versions.

다른 모듈에서 사용되는 공통 헤더 파일에서 형식을 정의하는 경우 버전이 지정된 시각화는 지정된 모듈 버전에 형식이 있는 경우에만 표시됩니다.If a common header file that is used by different modules defines a type, the versioned visualization appears only when the type is in the specified module version.

이 예제에서는 버전 1.0부터 1.5 사이의 Windows.UI.Xaml.dll에서 확인할 수 있는 DirectUI::Border 형식에만 시각화를 적용할 수 있습니다.In the following example, the visualization is applicable only for the DirectUI::Border type found in the Windows.UI.Xaml.dll from version 1.0 to 1.5.

<Type Name="DirectUI::Border">
  <Version Name="Windows.UI.Xaml.dll" Min="1.0" Max="1.5"/>
  <DisplayString>{{Name = {*(m_pDO->m_pstrName)}}}</DisplayString>
  <Expand>
    <ExpandedItem>*(CBorder*)(m_pDO)</ExpandedItem>
  </Expand>
</Type>

MinMax가 모두 필요하지는 않습니다.You don't need both Min and Max. 이들은 선택적 특성입니다.They are optional attributes. 와일드카드 문자가 지원되지 않습니다.No wildcard characters are supported.

Name 특성은 filename. ext 형식으로 되어 있습니다(예: hello.exe 또는 some.dll).The Name attribute is in the format filename.ext, such as hello.exe or some.dll. 경로 이름이 허용되지 않습니다.No path names are allowed.

DisplayString 요소DisplayString element

DisplayString 요소는 변수의 값으로 표시할 문자열을 지정합니다.The DisplayString element specifies a string to show as the value of a variable. 또한 식과 혼합된 임의의 문자열을 허용합니다.It accepts arbitrary strings mixed with expressions. 중괄호 내의 모든 항목은 식으로 해석됩니다.Everything inside curly braces is interpreted as an expression. 예를 들어, 다음 DisplayString 항목은For instance, the following DisplayString entry:

<Type Name="CPoint">
  <DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>

CPoint 형식의 변수가 다음 그림과 같이 표시됨을 의미합니다.Means that variables of type CPoint display as in this illustration:

DisplayString 요소 사용Use a DisplayString element

DisplayString 식에서 CPoint의 멤버인 xy는 중괄호 내에 있으므로 해당 값이 계산됩니다.In the DisplayString expression, x and y, which are members of CPoint, are inside curly braces, so their values are evaluated. 또한 이 예제에서 이중 중괄호({{ 또는 }} )를 사용하여 중괄호를 이스케이프하는 방법을 확인할 수 있습니다.The example also shows how you can escape a curly brace by using double curly braces ( {{ or }} ).

참고

DisplayString 요소는 임의 문자열 및 중괄호 구문을 허용하는 유일한 요소입니다.The DisplayString element is the only element that accepts arbitrary strings and curly brace syntax. 다른 모든 시각화 요소는 디버거가 계산할 수 있는 식만 허용합니다.All other visualization elements accept only expressions that the debugger can evaluate.

StringView 요소StringView element

StringView 요소는 디버거가 기본 제공 텍스트 시각화 도우미에 보낼 수 있는 값을 정의합니다.The StringView element defines a value that the debugger can send to the built-in text visualizer. 예를 들어 ATL::CStringT 형식에 다음 시각화가 제공될 경우For example, given the following visualization for the ATL::CStringT type:

<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
  <DisplayString>{m_pszData,su}</DisplayString>
</Type>

CStringT 개체는 변수 창에 다음 예제와 같이 표시됩니다.The CStringT object displays in a variable window like this example:

CStringT DisplayString 요소CStringT DisplayString element

StringView 요소는 디버거에게 값을 텍스트 시각화로 표시하도록 지시합니다.Adding a StringView element tells the debugger it can display the value as a text visualization.

<Type Name="ATL::CStringT&lt;wchar_t,*&gt;">
  <DisplayString>{m_pszData,su}</DisplayString>
  <StringView>m_pszData,su</StringView>
</Type>

디버그하는 동안 변수 옆에 있는 돋보기 아이콘을 선택하고 텍스트 시각화 도우미를 선택하여 m_pszData가 가리키는 문자열을 표시할 수 있습니다.During debugging, you can select the magnifying glass icon next to the variable, and then select Text Visualizer to display the string that m_pszData points to.

StringView 시각화 도우미가 있는 CStringT 데이터CStringT data with StringView visualizer

{m_pszData,su} 식에는 값을 유니코드 문자열로 표시하기 위한 C++ 형식 지정자 su가 포함되어 있습니다.The expression {m_pszData,su} includes a C++ format specifier su, to display the value as a Unicode string. 자세한 내용은 C++의 형식 지정자 를 참조하세요.For more information, see Format specifiers in C++.

Expand 요소Expand element

선택적 Expand 노드는 변수 창에서 형식을 확장할 때 시각화된 형식의 자식을 사용자 지정합니다.The optional Expand node customizes the children of a visualized type when you expand the type in a variable window. Expand 노드는 자식 요소를 정의하는 자식 노드의 목록을 허용합니다.The Expand node accepts a list of child nodes that define the child elements.

  • 시각화 항목에 Expand 노드가 지정되지 않은 경우 자식은 기본 확장 규칙을 사용합니다.If an Expand node isn't specified in a visualization entry, the children use the default expansion rules.

  • Expand 노드가 아래에 자식 노드 없이 지정된 경우 형식을 디버거 창에서 확장할 수 없습니다.If an Expand node is specified with no child nodes under it, the type isn't expandable in the debugger windows.

항목 확장Item expansion

Item 요소는 Expand 노드의 가장 기본적이고 공통적인 요소입니다.The Item element is the most basic and common element in an Expand node. Item 은 단일 자식 요소를 정의합니다.Item defines a single child element. 예를 들어 top, left, rightbottom 필드가 있는 CRect 클래스에는 다음 시각화 항목이 있습니다.For example, a CRect class with fields top, left, right, and bottom has the following visualization entry:

<Type Name="CRect">
  <DisplayString>{{top={top} bottom={bottom} left={left} right={right}}}</DisplayString>
  <Expand>
    <Item Name="Width">right - left</Item>
    <Item Name="Height">bottom - top</Item>
  </Expand>
</Type>

디버거 창에서 CRect 형식은 다음 예제와 같이 표시됩니다.In the debugger window, the CRect type looks like this example:

Item 요소 확장이 있는 CRectCRect with Item element expansion

디버거는 WidthHeight 요소에 지정된 식을 계산하고 변수 창의 열에 값을 표시합니다.The debugger evaluates the expressions specified in the Width and Height elements, and shows the values in the Value column of the variable window.

디버거는 모든 사용자 지정 확장에 [Raw 뷰] 노드를 자동으로 만듭니다.The debugger automatically creates the [Raw View] node for every custom expansion. 위의 스크린샷은 개체의 기본 Raw 뷰가 Natvis 시각화와 어떻게 다른지를 보여 주기 위해 확장된 [Raw 뷰] 노드를 표시합니다.The preceding screenshot displays the [Raw View] node expanded, to show how the default raw view of the object differs from its Natvis visualization. 기본 확장은 기본 클래스의 하위 트리를 생성하고 기본 클래스의 모든 데이터 멤버를 자식으로 나열합니다.The default expansion creates a subtree for the base class, and lists all the data members of the base class as children.

참고

항목 요소의 식이 복합 형식을 가리키는 경우 항목 노드 자체를 확장할 수 있습니다.If the expression of the item element points to a complex type, the Item node itself is expandable.

SizeArrayItems expansion

ArrayItems 노드를 사용하면 Visual Studio 디버거가 형식을 배열로 해석하고 해당 개별 요소를 표시하도록 할 수 있습니다.Use the ArrayItems node to have the Visual Studio debugger interpret the type as an array and display its individual elements. std::vector 에 대한 시각화는 좋은 예입니다.The visualization for std::vector is a good example:

<Type Name="std::vector&lt;*&gt;">
  <DisplayString>{{size = {_Mylast - _Myfirst}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_Mylast - _Myfirst</Item>
    <Item Name="[capacity]">(_Myend - _Myfirst)</Item>
    <ArrayItems>
      <Size>_Mylast - _Myfirst</Size>
      <ValuePointer>_Myfirst</ValuePointer>
    </ArrayItems>
  </Expand>
</Type>

std::vector 는 변수 창에서 확장되는 경우 개별 요소를 표시합니다.A std::vector shows its individual elements when expanded in the variable window:

ArrayItems 확장을 사용하는 std::vectorstd::vector using ArrayItems expansion

ArrayItems 노드에는 다음 항목이 있어야 합니다.The ArrayItems node must have:

  • 디버거에서 배열의 길이를 파악하기 위한 Size 식(정수로 계산되어야 함)입니다.A Size expression (which must evaluate to an integer) for the debugger to understand the length of the array.
  • 첫 번째 요소를 가리키는 ValuePointer 식(void*가 아닌 요소 형식의 포인터여야 함).A ValuePointer expression that points to the first element (which must be a pointer of an element type that is not void*).

배열 하한의 기본값은 0입니다.The default value of the array lower bound is 0. 값을 재정의하려면 LowerBound 요소를 사용합니다.To override the value, use a LowerBound element. Visual Studio와 함께 제공되는 .natvis 파일에는 예제가 있습니다.The .natvis files shipped with Visual Studio have examples.

참고

형식 자체(예: CATLArray)가 이 연산자를 허용하지 않더라도 ArrayItems를 사용하는 모든 단차원 배열 시각화에서 [] 연산자(예: vector[i])를 사용할 수 있습니다.You can use the [] operator, for example vector[i], with any single-dimensional array visualization that uses ArrayItems, even if the type itself (for example CATLArray) does not allow this operator.

다차원 배열도 지정할 수 있습니다.You can also specify multi-dimensional arrays. 이 경우 디버거는 자식 요소를 올바르게 표시하는 데 약간의 정보가 필요합니다.In that case, the debugger needs slightly more information to properly display child elements:

<Type Name="Concurrency::array&lt;*,*&gt;">
  <DisplayString>extent = {_M_extent}</DisplayString>
  <Expand>
    <Item Name="extent">_M_extent</Item>
    <ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
      <Direction>Forward</Direction>
      <Rank>$T2</Rank>
      <Size>_M_extent._M_base[$i]</Size>
      <ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
    </ArrayItems>
  </Expand>
</Type>
  • Direction은 배열이 행 중심 순서인지 열 중심 순서인지를 지정합니다.Direction specifies whether the array is in row-major or column-major order.
  • Rank 는 배열의 차수를 지정합니다.Rank specifies the rank of the array.
  • Size 요소는 해당 차원에서 배열의 길이를 확인하기 위해 차원 인덱스로 대체되는 암시적 $i 매개 변수를 허용합니다.The Size element accepts the implicit $i parameter, which it substitutes with the dimension index to find the length of the array in that dimension. 예를 들어 이전 예제에서 _M_extent.M_base[0] 식에는 0차원의 길이를 지정하고, _M_extent._M_base[1] 식에는 1차원의 길이를 지정해야 합니다.In the previous example, the expression _M_extent.M_base[0] should give the length of the 0th dimension, _M_extent._M_base[1] the 1st, and so on.

다음은 2차원 Concurrency::array 개체가 디버거 창에서 어떻게 나타나는지를 보여 줍니다.Here's how a two-dimensional Concurrency::array object looks in the debugger window:

ArrayItems 확장이 있는 2차원 배열Two-dimensional array with ArrayItems expansion

IndexListItems 확장IndexListItems expansion

메모리에 배열 요소가 연속적으로 배치된 경우에만 ArrayItems 확장을 사용할 수 있습니다.You can use ArrayItems expansion only if the array elements are laid out contiguously in memory. 디버거는 단순히 포인터를 늘리는 방식으로 다음 요소로 이동합니다.The debugger gets to the next element by simply incrementing its pointer. 값 노드에 대한 인덱스를 조작해야 하는 경우 IndexListItems 노드를 사용합니다.If you need to manipulate the index to the value node, use IndexListItems nodes. IndexListItems 노드를 사용하는 시각화는 다음과 같습니다.Here's a visualization with an IndexListItems node:

<Type Name="Concurrency::multi_link_registry&lt;*&gt;">
  <DisplayString>{{size = {_M_vector._M_index}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_M_vector._M_index</Item>
    <IndexListItems>
      <Size>_M_vector._M_index</Size>
      <ValueNode>*(_M_vector._M_array[$i])</ValueNode>
    </IndexListItems>
  </Expand>
</Type>

ArrayItemsIndexListItems 간의 유일한 차이점은 암시적 $i 매개 변수와 함께 i번째 요소에 대한 전체 식이 필요한 ValueNode입니다.The only difference between ArrayItems and IndexListItems is the ValueNode, which expects the full expression to the ith element with the implicit $i parameter.

참고

형식 자체(예: CATLArray)가 이 연산자를 허용하지 않더라도 IndexListItems를 사용하는 모든 단차원 배열 시각화에서 [] 연산자(예: vector[i])를 사용할 수 있습니다.You can use the [] operator, for example vector[i], with any single-dimensional array visualization that uses IndexListItems, even if the type itself (for example CATLArray) does not allow this operator.

LinkedListItems 확장LinkedListItems expansion

시각화된 형식이 링크된 목록을 나타내는 경우 디버거에서는 LinkedListItems 노드를 사용하여 해당 자식을 표시할 수 있습니다.If the visualized type represents a linked list, the debugger can display its children by using a LinkedListItems node. CAtlList 형식에 대한 다음 시각화는 LinkedListItems를 사용합니다.The following visualization for the CAtlList type uses LinkedListItems:

<Type Name="ATL::CAtlList&lt;*,*&gt;">
  <DisplayString>{{Count = {m_nElements}}}</DisplayString>
  <Expand>
    <Item Name="Count">m_nElements</Item>
    <LinkedListItems>
      <Size>m_nElements</Size>
      <HeadPointer>m_pHead</HeadPointer>
      <NextPointer>m_pNext</NextPointer>
      <ValueNode>m_element</ValueNode>
    </LinkedListItems>
  </Expand>
</Type>

Size 요소는 목록의 길이를 참조합니다.The Size element refers to the length of the list. HeadPointer 는 첫 번째 요소를 가리키고, NextPointer 는 다음 요소를 참조하며, ValueNode 는 항목의 값을 참조합니다.HeadPointer points to the first element, NextPointer refers to the next element, and ValueNode refers to the value of the item.

디버거는 NextPointerValueNode 식을 부모 목록 형식이 아닌 LinkedListItems 노드 요소의 컨텍스트에서 계산합니다.The debugger evaluates the NextPointer and ValueNode expressions in the context of the LinkedListItems node element, not the parent list type. 앞의 예제에서 CAtlList에는 연결된 목록의 노드인 CNode 클래스(atlcoll.h에 있음)가 있습니다.In the preceding example, CAtlList has a CNode class (found in atlcoll.h) that is a node of the linked list. m_pNextm_elementCAtlList 클래스가 아니라 해당 CNode 클래스의 필드입니다.m_pNext and m_element are fields of that CNode class, not of the CAtlList class.

ValueNode는 비어 있거나 this를 사용하여 LinkedListItems 노드 자체를 참조할 수 있습니다.ValueNode can be left empty, or use this to refer to the LinkedListItems node itself.

CustomListItems 확장CustomListItems expansion

CustomListItems 확장을 사용하여 해시 테이블 같은 데이터 구조 전송에 대한 사용자 지정 논리를 작성할 수 있습니다.The CustomListItems expansion allows you to write custom logic for traversing a data structure such as a hashtable. CustomListItems를 사용하면 계산해야 하는 모든 항목에 C++ 식을 사용할 수 있는 데이터 구조체를 시각할 수 있지만, ArrayItems, IndexListItems 또는 LinkedListItems에는 적합하지 않습니다.Use CustomListItems to visualize data structures that can use C++ expressions for everything you need to evaluate, but don't quite fit the mold for ArrayItems, IndexListItems, or LinkedListItems.

Exec를 사용하여 확장에 정의된 변수 및 개체를 사용하여 CustomListItems 확장 내에서 코드를 실행할 수 있습니다.You can use Exec to execute code inside of a CustomListItems expansion, using the variables and objects defined in the expansion. Exec에서 논리 연산자, 산술 연산자 및 대입 연산자를 사용할 수 있습니다.You can use logical operators, arithmetic operators, and assignment operators with Exec. C++ 식 계산기에서 지원되는 디버거 내장 함수를 제외하고 Exec를 사용하여 함수를 계산할 수 없습니다.You can't use Exec to evaluate functions, except for debugger intrinsic functions supported by the C++ expression evaluator.

CAtlMap에 대한 다음 시각화 도우미는 CustomListItems가 적합한 좋은 예입니다.The following visualizer for CAtlMap is an excellent example where CustomListItems is appropriate.

<Type Name="ATL::CAtlMap&lt;*,*,*,*&gt;">
    <AlternativeType Name="ATL::CMapToInterface&lt;*,*,*&gt;"/>
    <AlternativeType Name="ATL::CMapToAutoPtr&lt;*,*,*&gt;"/>
    <DisplayString>{{Count = {m_nElements}}}</DisplayString>
    <Expand>
      <CustomListItems MaxItemsPerView="5000" ExcludeView="Test">
        <Variable Name="iBucket" InitialValue="-1" />
        <Variable Name="pBucket" InitialValue="m_ppBins == nullptr ? nullptr : *m_ppBins" />
        <Variable Name="iBucketIncrement" InitialValue="-1" />

        <Size>m_nElements</Size>
        <Exec>pBucket = nullptr</Exec>
        <Loop>
          <If Condition="pBucket == nullptr">
            <Exec>iBucket++</Exec>
            <Exec>iBucketIncrement = __findnonnull(m_ppBins + iBucket, m_nBins - iBucket)</Exec>
            <Break Condition="iBucketIncrement == -1" />
            <Exec>iBucket += iBucketIncrement</Exec>
            <Exec>pBucket = m_ppBins[iBucket]</Exec>
          </If>
          <Item>pBucket,na</Item>
          <Exec>pBucket = pBucket->m_pNext</Exec>
        </Loop>
      </CustomListItems>
    </Expand>
</Type>

TreeItems 확장TreeItems expansion

시각화된 형식이 트리를 나타내는 경우 디버거에서는 TreeItems 노드를 사용하여 트리를 단계별로 진행하면서 해당 자식을 표시할 수 있습니다.If the visualized type represents a tree, the debugger can walk the tree and display its children by using a TreeItems node. 다음은 TreeItems 노드를 사용하는 std::map 형식에 대한 시각화입니다.Here's the visualization for the std::map type using a TreeItems node:

<Type Name="std::map&lt;*&gt;">
  <DisplayString>{{size = {_Mysize}}}</DisplayString>
  <Expand>
    <Item Name="[size]">_Mysize</Item>
    <Item Name="[comp]">comp</Item>
    <TreeItems>
      <Size>_Mysize</Size>
      <HeadPointer>_Myhead->_Parent</HeadPointer>
      <LeftPointer>_Left</LeftPointer>
      <RightPointer>_Right</RightPointer>
      <ValueNode Condition="!((bool)_Isnil)">_Myval</ValueNode>
    </TreeItems>
  </Expand>
</Type>

이 구문은 LinkedListItems 노드와 비슷합니다.The syntax is similar to the LinkedListItems node. LeftPointer, RightPointerValueNode는 트리 노드 클래스의 컨텍스트에서 평가됩니다.LeftPointer, RightPointer, and ValueNode are evaluated under the context of the tree node class. ValueNode는 비어 있거나 this를 사용하여 TreeItems 노드 자체를 참조할 수 있습니다.ValueNode can be left empty or use this to refer to the TreeItems node itself.

ExpandedItem 확장ExpandedItem expansion

ExpandedItem 요소는 기본 클래스 또는 데이터 멤버를 시각화된 형식의 자식이었던 것처럼 표시하는 방식으로 집계된 자식 뷰를 생성합니다.The ExpandedItem element generates an aggregated child view by displaying properties of base classes or data members as if they were children of the visualized type. 디버거는 지정된 식을 계산하고 결과의 자식 노드를 시각화된 형식의 자식 목록에 추가합니다.The debugger evaluates the specified expression, and appends the child nodes of the result to the child list of the visualized type.

예를 들어, 스마트 포인터 auto_ptr<vector<int>> 형식은 일반적으로 다음과 같이 표시됩니다.For example, the smart pointer type auto_ptr<vector<int>> typically displays as:

auto_ptr<vector<int>> 기본 확장auto_ptr<vector<int>> default expansion

벡터 값을 확인하려면 변수 창에서 두 개의 수준을 드릴다운하여 _Myptr 멤버를 통과해야 합니다.To see the values of the vector, you have to drill down two levels in the variable window, passing through the _Myptr member. ExpandedItem 요소를 추가하면 계층 구조에서 _Myptr 변수를 제거하고 벡터 요소를 바로 확인할 수 있습니다.By adding an ExpandedItem element, you can eliminate the _Myptr variable from the hierarchy and directly view the vector elements:

<Type Name="std::auto_ptr&lt;*&gt;">
  <DisplayString>auto_ptr {*_Myptr}</DisplayString>
  <Expand>
    <ExpandedItem>_Myptr</ExpandedItem>
  </Expand>
</Type>

auto_ptr<vector<int>> ExpandedItem 확장auto_ptr<vector<int>> ExpandedItem expansion

다음 예제에서는 파생 클래스에서 기본 클래스의 속성을 집계하는 방법을 보여 줍니다.The following example shows how to aggregate properties from the base class in a derived class. CPanel 클래스가 CFrameworkElement에서 파생된다고 가정해 보겠습니다.Suppose the CPanel class derives from CFrameworkElement. ExpandedItem 노드 시각화는 기본 CFrameworkElement 클래스에서 가져온 속성을 반복하는 대신, 이러한 속성을 CPanel 클래스의 자식 목록에 추가합니다.Instead of repeating the properties that come from the base CFrameworkElement class, the ExpandedItem node visualization appends those properties to the child list of the CPanel class.

<Type Name="CPanel">
  <DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
  <Expand>
    <Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
    <ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
  </Expand>
</Type>

이때 파생된 클래스에 대해 시각화 일치를 해제하는 nd 형식 지정자가 필요합니다.The nd format specifier, which turns off visualization matching for the derived class, is necessary here. 이 형식 지정자가 없으면 *(CFrameworkElement*)this 식으로 인해 CPanel 시각화가 다시 적용되는데, 이는 기본 시각화 형식 일치 규칙에서 이를 가장 적합한 것으로 인식하기 때문입니다.Otherwise, the expression *(CFrameworkElement*)this would cause the CPanel visualization to be applied again, because the default visualization type matching rules consider it the most appropriate one. nd 형식 지정자를 사용하여 디버거가 기본 클래스 시각화를 사용하거나 기본 클래스에 시각화가 없는 경우 기본 확장을 사용하도록 지시합니다.Use the nd format specifier to instruct the debugger to use the base class visualization, or the default expansion if the base class has no visualization.

가상 항목 확장Synthetic item expansion

ExpandedItem 요소는 계층 구조를 제거하여 데이터를 보다 평면적으로 표시하지만 Synthetic 노드는 그 반대입니다.While the ExpandedItem element provides a flatter view of data by eliminating hierarchies, the Synthetic node does the opposite. 이를 통해 식의 결과가 아닌 인위적 자식 요소를 만들 수 있습니다.It allows you to create an artificial child element that isn't a result of an expression. 인위적 요소에는 자체 자식 요소가 있을 수 있습니다.The artificial element can have child elements of its own. 다음 예의 Concurrency::array 형식에 대한 시각화에서는 사용자에게 진단 메시지를 표시하기 위해 Synthetic 노드를 사용합니다.In the following example, the visualization for the Concurrency::array type uses a Synthetic node to show a diagnostic message to the user:

<Type Name="Concurrency::array&lt;*,*&gt;">
  <DisplayString>extent = {_M_extent}</DisplayString>
  <Expand>
    <Item Name="extent" Condition="_M_buffer_descriptor._M_data_ptr == 0">_M_extent</Item>
    <ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
      <Rank>$T2</Rank>
      <Size>_M_extent._M_base[$i]</Size>
      <ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
    </ArrayItems>
    <Synthetic Name="Array" Condition="_M_buffer_descriptor._M_data_ptr == 0">
      <DisplayString>Array members can be viewed only under the GPU debugger</DisplayString>
    </Synthetic>
  </Expand>
</Type>

가상 요소 확장이 있는 Concurrency::ArrayConcurrency::Array with Synthetic element expansion

HResult 요소HResult element

HResult 요소를 사용하면 디버거 창에서 HRESULT에 대해 표시되는 정보를 사용자 지정할 수 있습니다.The HResult element lets you customize the information shown for an HRESULT in debugger windows. HRValue 요소에는 사용자 지정할 HRESULT의 32비트 값이 포함되어 있어야 합니다.The HRValue element must contain the 32-bit value of the HRESULT that is to be customized. HRDescription 요소에는 디버거 창에 표시할 정보가 포함되어 있습니다.The HRDescription element contains the information to show in the debugger window.


<HResult Name="MY_E_COLLECTION_NOELEMENTS">
  <HRValue>0xABC0123</HRValue>
  <HRDescription>No elements in the collection.</HRDescription>
</HResult>

UIVisualizer 요소UIVisualizer element

UIVisualizer 요소는 디버거에 그래픽 시각화 도우미 플러그 인을 등록합니다.A UIVisualizer element registers a graphical visualizer plug-in with the debugger. 그래픽 시각화 도우미는 해당 데이터 형식과 일치하는 방식으로 변수 또는 개체를 표시하는 대화 상자 또는 다른 인터페이스를 만듭니다.A graphical visualizer creates a dialog box or other interface that shows a variable or object in a way consistent with its data type. 시각화 도우미 플러그 인은 VSPackage로 작성해야 하며 디버거에서 사용할 수 있는 서비스를 노출해야 합니다.The visualizer plug-in must be authored as a VSPackage, and must expose a service that the debugger can consume. .natvis 파일에는 플러그 인의 이름, 노출된 서비스의 GUID, 시각화할 수 있는 형식 같은 플러그 인 등록 정보가 포함되어 있습니다.The .natvis file contains registration information for the plug-in, such as its name, the GUID of the exposed service, and the types it can visualize.

UIVisualizer 요소의 예는 다음과 같습니다.Here's an example of a UIVisualizer element:

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
        Id="1" MenuName="Vector Visualizer"/>
    <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
        Id="2" MenuName="List Visualizer"/>
.
.
</AutoVisualizer>
  • ServiceId - Id 특성 쌍은 UIVisualizer를 식별합니다.A ServiceId - Id attribute pair identifies a UIVisualizer. ServiceId는 시각화 도우미 패키지에서 노출하는 서비스의 GUID입니다.The ServiceId is the GUID of the service the visualizer package exposes. Id는 서비스에서 두 개 이상 제공하는 경우 시각화 도우미를 구분하는 고유 식별자입니다.Id is a unique identifier that differentiates visualizers, if a service provides more than one. 위의 예제에서는 동일한 시각화 도우미 서비스에서 두 개의 시각화 도우미를 제공합니다.In the preceding example, the same visualizer service provides two visualizers.

  • MenuName 특성은 디버거의 돋보기 아이콘 옆에 있는 드롭다운에 표시되는 시각화 도우미 이름을 정의합니다.The MenuName attribute defines a visualizer name to display in the drop-down next to the magnifying glass icon in the debugger. 예를 들어:For example:

    UIVisualizer 메뉴 바로 가기 메뉴UIVisualizer menu shortcut menu

.natvis 파일에 정의된 각 형식에는 해당 형식을 표시할 수 있는 모든 UI 시각화 도우미가 명시적으로 나열되어야 합니다.Each type defined in the .natvis file must explicitly list any UI visualizers that can display it. 디버거는 형식 항목의 시각화 도우미 참조를 등록된 시각화 도우미와 일치시킵니다.The debugger matches the visualizer references in the type entries with the registered visualizers. 예를 들어 std::vector에 대한 다음 형식 항목은 앞의 예제에서 UIVisualizer를 참조합니다.For example, the following type entry for std::vector references the UIVisualizer in the preceding example.

<Type Name="std::vector&lt;int,*&gt;">
  <UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>

메모리 내 비트맵을 보는 데 사용되는 이미지 조사식 확장의 UIVisualizer 예시를 볼 수 있습니다.You can see an example of a UIVisualizer in the Image Watch extension used to view in-memory bitmaps.

CustomVisualizer 요소CustomVisualizer element

CustomVisualizer는 Visual Studio 코드에서 시각화를 제어하기 위해 작성하는 VSIX 확장을 지정하는 확장 지점입니다.CustomVisualizer is an extensibility point that specifies a VSIX extension that you write to control visualizations in Visual Studio code. VSIX 확장 작성 방법에 대한 자세한 내용은 Visual Studio SDK를 참조하세요.For more information about writing VSIX extensions, see the Visual Studio SDK.

사용자 지정 시각화 도우미를 작성하는 데에는 XML Natvis 정의보다 많은 작업이 필요하지만 Natvis에서 지원하거나 지원하지 않는 사항을 신경쓰지 않아도 됩니다.It's a lot more work to write a custom visualizer than an XML Natvis definition, but you're free from constraints about what Natvis does or doesn't support. 사용자 지정 시각화 도우미는 디버거 프로세스를 쿼리하고 수정하거나 Visual Studio의 다른 부분과 통신할 수 있는 전체 디버거 확장 API에 액세스할 수 있습니다.Custom visualizers have access to the full set of debugger extensibility APIs, which can query and modify the debuggee process or communicate with other parts of Visual Studio.

CustomVisualizer 요소에 Condition, IncludeViewExcludeView 특성을 사용할 수 있습니다.You can use the Condition, IncludeView, and ExcludeView attributes on CustomVisualizer elements.

제한 사항Limitations

Natvis 사용자 지정은 클래스 및 구조체에서 작동하지만 typedef에는 적용되지 않습니다.Natvis customizations work with classes and structs, but not typedefs.

Natvis는 기본 형식(예: int, bool) 또는 기본 형식 포인터에 대한 시각화 도우미를 지원하지 않습니다.Natvis does not support visualizers for primitive types (for example, int, bool) or for pointers to primitive types. 이 시나리오에서 한 가지 옵션은 사용 사례에 적합한 형식 지정자를 사용하는 것입니다.In this scenario, one option is to use the format specifier appropriate to your use case. 예를 들어 코드에서 double* mydoublearray를 사용하는 경우 디버거의 조사식 창에서 처음 100개 요소를 표시하는 mydoublearray, [100] 식과 같은 배열 형식 지정자를 사용할 수 있습니다.For example, if you use double* mydoublearray in your code, then you can use an array format specifier in the debugger's Watch window, such as the expression mydoublearray, [100], which shows the first 100 elements.