{"id":171,"date":"2014-04-02T21:39:04","date_gmt":"2014-04-03T04:39:04","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=171"},"modified":"2023-03-29T17:57:12","modified_gmt":"2023-03-30T00:57:12","slug":"visualizergettingstarted","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/w\/tutorials\/visualizergettingstarted\/","title":{"rendered":"Getting started with VisualGDB Type Visualizers"},"content":{"rendered":"<p>Type visualizers are a powerful mechanism allowing you to display the variable values during debugging in a more user-friendly way than simply listing all members. This is extremely useful if your program contains custom STL-like containers or string classes.<\/p>\n<p>This tutorial shows the very basics of making a simple type visualizer and registering it with VisualGDB. It will simply make VisualGDB show &#8220;Hello, Visual Studio&#8221; instead of the actual value for a given C++ class.<\/p>\n<ol>\n<li>Create a simple &#8220;Hello, World&#8221; application with VisualGDB. Although the type visualizers will work for all projects types, the most simple way to start is by creating a MinGW application (follow <a href=\"\/tutorials\/mingw\">this tutorial<\/a>).<\/li>\n<li>Replace the contents of the main C++ file with the following:\n<pre class=\"\">#include&lt;stdio.h&gt;\r\n\r\ntemplate &lt;class _Type&gt; class VeryBasicArray\r\n{\r\nprivate:\r\n    size_t m_Count;\r\n    _Type *m_pData; \r\n};\r\n\r\nint main()\r\n{\r\n    VeryBasicArray&lt;int&gt; test;\r\n    return 0;\r\n}<\/pre>\n<\/li>\n<li>Place a breakpoint at the &#8220;return 0&#8221; line and start debugging. When the breakpoint is hit, hover the mouse over &#8220;test&#8221; to see its value:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/01-expval.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/01-expval.png\" alt=\"01-expval\" width=\"547\" height=\"302\" \/><\/a><\/li>\n<li>We will now make a VisualGDB plugin that will replace the value of test (<strong>&#8220;m_Count = 68, m_pData = &#8230;&#8221;<\/strong>) with a custom string. Please refer to the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/N_VisualGDBExpressions.htm\">SDK reference<\/a> for more information about things that type visualizers can change.<\/li>\n<li>Start Visual Studio as Administrator so that it can write to the VisualGDB installation directory inside Program Files. Go to FIle-&gt;New Project and select C# -&gt; Class Library:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/02-csproj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/02-csproj.png\" alt=\"02-csproj\" width=\"800\" height=\"498\" \/><\/a><\/li>\n<li>Right-click on the newly created project, select &#8220;Add Reference&#8221;. Select &#8220;Browse&#8221; and point to the <strong> VisualGDBExpressions.dll<\/strong> assembly inside the VisualGDB directory.<\/li>\n<li>Right-click on the project and select &#8220;Properties&#8221;. Go to the Debug tab, select &#8220;Start External Program&#8221; and specify the path to your Visual Studio&#8217;s <strong>devenv.exe:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/03-debugsettings.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/03-debugsettings.png\" alt=\"03-debugsettings\" width=\"1076\" height=\"662\" \/><\/a><\/strong><\/li>\n<li>Go to the Build Events page and specify the following post-build command line:\n<pre>copy \/y $(TargetPath) \"C:\\Program Files (x86)\\Sysprogs\\VisualGDB\\TypeVisualizers<\/pre>\n<p>Ensure that the VisualGDB installation directory is specified correctly.<\/li>\n<li>Add a file called <strong>MyBasicFilter.cs<\/strong> with the following contents:\n<pre class=\"\">using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing VisualGDBExpressions;\r\n \r\nnamespace MyTypeVisualizer\r\n{\r\n    class MyBasicFilter : TypeListBasedExpressionFilter\r\n    {\r\n        public MyBasicFilter()\r\n            : base(\"VeryBasicArray&lt;\")\r\n        {\r\n        }\r\n\r\n        protected override IExpression DoAttach(\r\n             IExpression expr, \r\n             IExpressionEvaluator evaluator)\r\n        {\r\n            return new StaticExpressionFilter(expr) \r\n                 { \r\n                     ValueOverride = new ExpressionValue.Custom(\r\n                                         \"Hello, Visual Studio\")\r\n                 };\r\n        }\r\n    }\r\n }<\/pre>\n<\/li>\n<li>Add a file called <strong>Factory.cs<\/strong> with the following contents:\n<pre class=\"\">using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing VisualGDBExpressions;\r\n\r\nnamespace MyTypeVisualizer\r\n{\r\n    public class MyFilterFactory : IExpressionFilterFactory\r\n    {\r\n        public IEnumerable&lt;ExpressionFilterRecord&gt;\r\n             CreateExpressionFilters()\r\n        {\r\n            return new ExpressionFilterRecord[] \r\n            {\r\n                 new MyBasicFilter().Record\r\n            };\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<\/li>\n<li>Build the project. Ensure that your DLL has been copied to the <strong>TypeVisualizers<\/strong> directory inside the VisualGDB directory (the directory should already contain <strong>STLTypeVisualizer.dll<\/strong>).<\/li>\n<li>Start debugging your project. Another instance of Visual Studio will be executed. Open your VisualGDB-based project using that Visual Studio. Put a breakpoint on the return statement and run the project.<\/li>\n<li>Hover the mouse over &#8220;test&#8221; to see the modified value:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/04-hooked.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/04-hooked.png\" alt=\"04-hooked\" width=\"533\" height=\"299\" \/><\/a><\/li>\n<li>Go back to the outer Visual Studio instance, set a breakpoint inside the DoAttach() function, go back to the inner Visual Studio and hover the mouse over <strong>test<\/strong> again. A breakpoint will be triggered.<br \/>\n<span class=\"warning\">Do not evaluate the <strong> IExpression<\/strong> members in the outer Visual Studio. This would require a cross-thread call that cannot be performed while your plugin is stopped at a breakpoint.<\/span><\/li>\n<li>Use edit-and-continue to copy the value of expr.Type into a temporary variable. Run the newly created statement using the &#8220;Set next statement&#8221; and &#8220;Step&#8221; commands:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/05-enc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/VisualizerGettingStarted\/05-enc.png\" alt=\"05-enc\" width=\"617\" height=\"241\" \/><\/a><\/li>\n<\/ol>\n<p>Now we are ready to make a meaningful expression visualizer. Follow the <a href=\"https:\/\/visualgdb.com\/w\/tutorials\/simplearrayvisualizer\/\">next tutorial<\/a> to make this visualizer display array contents in a structured way.<\/p>\n<h2>The explanation<\/h2>\n<p>This section explains how the basic visualizer implemented above works.<\/p>\n<p>When we inherited the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_TypeListBasedExpressionFilter.htm\">TypeListBasedExpressionFilter<\/a> class and specified &#8220;VeryBasicArray&lt;&#8221; in the constructor, we have created a simple filter that only attaches itself to instances of the VeryBasicArray class.<\/p>\n<p>The DoAttach() method essentially allows replacing an expression (the original value) with another arbitrary expression returned by the method. However, instead of implementing the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_IExpression.htm\"> IExpression<\/a> interface manually we have used the <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_StaticExpressionFilter.htm\">StaticExpressionFilter<\/a> class to make a clone of the original expression replacing the value with our string (represented as an instance of <a href=\"https:\/\/visualgdb.com\/reference\/extensibility\/html\/T_VisualGDBExpressions_ExpressionValue_Custom.htm\"> ExpressionValue.Custom<\/a>).<\/p>\n<h2>Source code<\/h2>\n<p>You can download the source code for the example in this tutorial <a href=\"http:\/\/sysprogs.com\/files\/visualgdb\/tutorials\/VisualizerTest-v1.zip\">here<\/a>. The code in the archive is provided under the BSD license.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Type visualizers are a powerful mechanism allowing you to display the variable values during debugging in a more user-friendly way<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/171"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=171"}],"version-history":[{"count":11,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/171\/revisions"}],"predecessor-version":[{"id":8037,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/171\/revisions\/8037"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}