<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Cluebat-man to the rescue : C++</title><link>http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx</link><description>Tags: C++</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Practical ATL: Solving the race condition in CAtlExeModuleT</title><link>http://msmvps.com/blogs/vandooren/archive/2009/04/15/solving-the-race-condition-in-catlexemodulet.aspx</link><pubDate>Wed, 15 Apr 2009 12:40:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1687784</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1687784</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1687784</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/04/15/solving-the-race-condition-in-catlexemodulet.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When I was spelunking through the ATL header for my previous articles (the class object plumbing) I discovered that there is a serious race condition in the server lifetime management.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I contacted the Microsoft C++ folks, and someone from the libraries group told me that this problem has already been fixed in the next release of Visual C++.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But since the issue still exists in all current ATL projects, I decided to write something about it and publish the fix which will circumvent the problem in the recent versions of ATL (7.0 and upwards if I am correct).&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The problem&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The module lock count of an ATL COM server is managed in the CAtlExeModuleT&amp;lt;T&amp;gt; class. It is this lock count that keeps the server alive as long as it is nonzero.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The CAtlExeModuleT&amp;lt;T&amp;gt; class manages its reference count via the&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComGlobalsThreadModel class increment and decrement methods. CComGlobalsThreadModel is a typedef for CComMultiThreadModel so these methods map to InterlockedIncrement and InterlockedDecrement&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The last module lock is released if&lt;br /&gt;- the class object itself has no more external connections (IExternalConnection), and&lt;br /&gt;- there are no more object instances.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As soon as the final module lock is released (module refcount is 0), the shutdown of the server is initiated, which will happen through either a WM_QUIT message or a win32 event object. In both cases there is a time window between the triggering of the shutdown, and the actual call to CoRevokeClassObject. This time window can be several seconds.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This time window causes a race condition between the server (which is already dying at that point) trying to revoke the class object, and a hypothetical client, requesting an interface pointer to the class object. Depending on how the race turns out, the client might end up with an S_OK HRESULT from CoGetClassObject, and an invalid interface pointer. This will cause a critical problem in the client, and may cause an application&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;crash.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The solution&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The proper way to manage the server lifetime is to use CoAddRefServerProcess and CoReleaseRefServerProcess to manage the module lockcount. Those functions will (according to MSDN http://msdn.microsoft.com/en-us/library/aa910552.aspx) suspend all class objects when the reference count drops to 0, in an atomic operation.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In that case, the server starts dying AFTER all class objects are suspended. Any incoming client request for the class object will spawn a new server process after the dying server has finished revoking its class objects.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The fix&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code for fixing this is simple. I simply created a new class that inherits from CAtlExeModuleT&amp;lt;T&amp;gt; and then overrides the Lock and Unlock methods.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CAtlExeModuleT_NoRace : &lt;span style="color:blue;"&gt;public&lt;/span&gt; CAtlExeModuleT&amp;lt;T&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; CAtlExeModuleT&amp;lt;T&amp;gt; base;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#if&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; _ATL_VER &amp;lt; 0x0A00&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LONG Lock(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoAddRefServerProcess();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; base::Lock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LONG Unlock(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoReleaseServerProcess();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; base::Unlock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#else&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;//removed compiler messages&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#endif&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I use CoxxxxServerProcess functions to explicitly manage the class object registration, and then I delegate to the base class which maintains its own reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The reason I do that is that the base::Unlock function is the one which triggers the module shutdown, and I don&amp;rsquo;t want to mess with that. And Unlock works only when paired with Lock, so the only thing I really need to do is to call the CoxxxxServerProcess routines to prevent possible activation requests. The rest is still done by CAtlExeModuleT&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I put a compiler condition around my implementation of the new Lock and Unlock methods, because they are only needed for current versions of ATL. The next version of ATL won&amp;rsquo;t have this problem, so it would be dangerous to meddle with the reference counting, especially since I cannot predict what side effects this may have.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The conditional compilation allows you to safely upgrade the project to the next version of ATL. The compiler messages which show up in the compiler output inform you that it is no longer needed to inherit from CAtlExeModuleT_NoRace as shown below:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuff_ServerModule : &lt;span style="color:blue;"&gt;public&lt;/span&gt; CAtlExeModuleT&lt;span style="background:silver;mso-highlight:silver;"&gt;_NoRace&lt;/span&gt;&amp;lt; CStuff_ServerModule &amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; :&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;DECLARE_LIBID(LIBID_Stuff_ServerLib)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;DECLARE_REGISTRY_APPID_RESOURCEID(IDR_STUFF_SERVER, &lt;span style="color:#a31515;"&gt;&amp;quot;{597B5DFF-DACE-42B0-9E49-54A09C10B2BB}&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The only thing you have to do to use my new module class is to include the header and change CAtlExeModuleT to CAtlExeModuleT_NoRace.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And if you upgrade the project to VC10, then you can simply change it back as indicated by the compiler output messages that are printed out when the compiler parses my class.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I was surprised that this bug was still in the ATL headers after all these years. When I contacted the VC++ team I was half expecting them to tell me that I had missed something. This issue is what caused CoAddRefServerProcess to be created after all, over a decade ago, so a COM programmer implementing lifetime management should be aware of it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;However, the modular and hierarchical nature of ATL made it easy to fix this problem, so I guess that is a plus for ATL. And mistakes happen. It is always a bit painful if it happens in widely used libraries, but I too have had my share of whoopsies over the years. It is sad but it happens.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The header file with the fix is attached to this blog post under the MIT license.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1687784" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.68.77.84/AtlExeModuleT_5F00_NoRace.zip" length="1536" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Practial ATL: Implementing a non-standard class object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/02/20/practial-atl-implementing-a-non-standard-class-object.aspx</link><pubDate>Fri, 20 Feb 2009 21:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1673035</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1673035</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1673035</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/02/20/practial-atl-implementing-a-non-standard-class-object.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In my previous article in this series, I explained how class objects are associated with COM objects, and how it all fits together.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Armed with that knowledge, I can now demonstrate how to provide a custom class object that will allow us to support parameterized construction.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you haven&amp;rsquo;t already read my previous article on class objects, please do so first because I am going to assume you did &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The non-standard class object interface: IStuffCreator&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A class object can have any interface you want, just like the COM object we have created earlier. It is just another COM object after all. My custom interface looks like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;[&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;object&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;uuid&lt;/span&gt;(6DD69CDB-3128-432b-B335-773A287E6F06),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;oleautomation&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;IStuffCreator Interface&amp;quot;&lt;/span&gt;),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;pointer_default&lt;/span&gt;(&lt;span style="color:blue;"&gt;unique&lt;/span&gt;)&lt;br /&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;interface&lt;/span&gt; IStuffCreator : IUnknown {&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;id&lt;/span&gt;(1), &lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;method MakeMeAStuff&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT MakeMeAStuff(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] BSTR name,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] REFIID riid,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;out&lt;/span&gt;, &lt;span style="color:blue;"&gt;iid_is&lt;/span&gt;(riid)] IUnknown** ppStuff);&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The bits between the square brackets are the attributes that are applied to this interface. &amp;lsquo;Object&amp;rsquo; specifies that it is a COM interface. The uuid specifies the GUID that identifies the interface. &amp;lsquo;oleautomation&amp;rsquo; specifies that the arguments being used are all automation compatible. The meaning of&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&amp;lsquo;helpstring&amp;rsquo; is pretty obvious, and pointer_default specifies the assumptions that the marshaller can make about pointers.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you want to know the details about it, then have a look in MSDN for MIDL attributes.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface itself is very simple. Instead of deriving from IDispatch like the IStuff interface, this interface derives from IUnknown. Deriving from IDispatch would only complicate matters without any benefit.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface has only one method, which is responsible for handing out new stuffs. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The parameter that will be used for constructing the CStuff instance itself is the &amp;lsquo;name&amp;rsquo; parameter. If the CStuff would need multiple parameters, they would have to be part of the parameter list so that they can be used at the time of construction. The riid and ppStuff parameters have the same meaning as those of CoCreateInstance.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The declaration of CStuffCreator&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If we want to implement this interface, we add a new C++ class with the name &amp;lsquo;CStuffCreator&amp;rsquo; to our project, and implement our IStuffCreator interface&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator:&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IStuffCreator,&lt;br /&gt;&lt;span style="color:blue;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComGlobalsThreadModel&amp;gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CStuffCreator(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;virtual&lt;/span&gt; ~CStuffCreator(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BEGIN_COM_MAP(CStuffCreator)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuffCreator)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;END_COM_MAP()&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//IStuffCreator methods&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT STDMETHODCALLTYPE MakeMeAStuff(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff);&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// helper method&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_CREATORFUNC* m_pfnCreateInstance;&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, it is pretty simple. The CComObjectRootEx base class helps with reference counting, and is the same that is used by the other COM objects in our project.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We add IStuffCreator to the interface map using the ATL macros, and then we simply declare the single &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;MakeMeAStuff&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; method that we need to implement.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The SetVoid method and the function pointer are part of the default C++ interface for class objects in ATL, and are explained in my previous article.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The implementation&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The implementation of CStuffCreator is even simpler than the declaration:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;HRESULT STDMETHODCALLTYPE CStuffCreator::MakeMeAStuff( &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IUnknown&amp;gt; newStuff;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = m_pfnCreateInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL, &lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;newStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; newStuff-&amp;gt;QueryInterface(riid, (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator::SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Ignore the &amp;lsquo;name&amp;rsquo; parameter for now. That will be used when we are going to initialize the new instance. The bare functionality of our class object is to use the function pointer to create a new instance. I could have done this in 1 step instead of 2 (the QueryInterface isn&amp;rsquo;t necessary at this point) but this way I can slide in some additional functionality later on.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And you can see now that the class object will receive the creator function pointer via the &amp;lsquo;SetVoid&amp;rsquo; method. This mechanism was explained in my previous article.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Parameterized construction&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The point of using a non-standard class object in this demonstration was to be able to create objects that need some sort of initialization before the client has access to them. Normally, ATL supports only default constructors using, because IClassFactory is a generic interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;For parameterized constructors, we are going to have to do something special.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are essentially 2 ways we can do this. The first is to change CStuff to have a parameterized constructor. But ATL can&amp;rsquo;t handle that, and it would mean we have to abandon the incredible convenience of being able to use the ATL::Creator&amp;lt;T&amp;gt; class, ATL::CComObject class, and other helper classes that take the pain out of COM.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Don Box wrote an article about parameterized construction, many years ago, and this was the approach he took. Of course, ATL was much simpler in those days, and abandoning it was perhaps less of an inconvenience.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The approach I am taking is much simpler: I cheat!&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;That&amp;rsquo;s right. I cheat. I am &lt;i style="mso-bidi-font-style:normal;"&gt;not&lt;/i&gt; going to implement parameterized constructors. I am going to fake it. But from the client&amp;rsquo;s point of view, it&amp;rsquo;s going to look exactly the same, so he won&amp;rsquo;t mind. And from the server&amp;rsquo;s point of view, it will be much simpler to implement, so everybody wins.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The second approach to implementing parameterized construction is to implement an internal interface on CStuff, which will be used for initializing it. The new CStuff instance will not be accessible to anyone until the first interface pointer is handed out by the class object. And we are the ones implementing the class interface, so we can make sure that the new instance is initialized properly before it is released into the wild.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The initialization interface&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface for initializing a CStuff is pretty simple (I left out the header for clarity):&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;interface&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; IStuffInit : IUnknown {&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;id&lt;/span&gt;(1), &lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;method InitStuffInstance&amp;quot;&lt;/span&gt;)]&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT InitStuffInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] BSTR Name);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Our CStuff instances are supposed to have a name, so that&amp;rsquo;s what needs to be in the init interface. If they would also need an address, a hat, and a pair of pants, we would have to put those in the parameter list of the InitStuffInstance method as well.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Implementing the initialization interface&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Implementing the interface in CStuff is easy I highlighted the changes that have to be made to the declaration.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// CStuff&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; ATL_NO_VTABLE CStuff :&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComMultiThreadModel&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComCoClass&amp;lt;CStuff, &amp;amp;CLSID_Stuff&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IDispatchImpl&amp;lt;IStuff, &amp;amp;IID_IStuff, &amp;amp;LIBID_Stuff_ServerLib, &lt;span style="color:green;"&gt;/*wMajor =*/&lt;/span&gt; 1, &lt;span style="color:green;"&gt;/*wMinor =*/&lt;/span&gt; 0&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;public&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; IStuffInit&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;private&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;CComBSTR m_Name;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;DECLARE_CLASSFACTORY_EX(CStuffCreator)&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// removed irrelevant stuff&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;BEGIN_COM_MAP(CStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IDispatch)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;COM_INTERFACE_ENTRY(IStuffInit)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;END_COM_MAP()&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// removed irrelevant stuff&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:green;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;HRESULT STDMETHODCALLTYPE InitStuffInstance(BSTR Name);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;First we add IStuffInit to the inheritance list, we add it to the COM map, and then we add the declaration for InitStuffInstance.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, the name has to be part of the objects state, so we add a CComBSTR variable to hold it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And finally, we use the DECLARE_CLASSFACTORY_EX macro to change the class object for CStuff from CComClassFactory to CStuffCreator.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The actual implementation of the interface consists of the simple code&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;STDMETHODIMP CStuff::InitStuffInstance(BSTR Name)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;m_Name = Name;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; S_OK;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Note the ease with which CComBSTR allows us to perform simple string operations.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Initializing the new CStuff object&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now that there is a dedicated function to handle the initialization, the changes to CStuffCreator are trivial:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;HRESULT STDMETHODCALLTYPE CStuffCreator::MakeMeAStuff( &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuffInit&amp;gt; newStuff;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = m_pfnCreateInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuffInit), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;newStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;hr = newStuff-&amp;gt;InitStuffInstance(name);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; newStuff-&amp;gt;QueryInterface(riid, (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;What about double initialization&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;By now you might be wondering: But what if the client application retrieves this interface and performs another initialization?&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;However, this will not be possible.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It&amp;rsquo;s true that I put the interface in our IDL file, and that I implemented it in the CStuff object. But I did not put that interface in the library declaration, nor did I put it in the interface list of the coclass.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So for all practical purposes, this interface is not accessible to the client application. If you are really paranoid, you could argue that an attacker might know the interface GUID, and guess the interface definition, and with some trial and error make it work.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Even then, the fix is quite simple. You can add a boolean to your class that indicates if the object was initialized or not. Set it to false in the constructor, and then the InitStuffInstance can either perform initialization if it is false and set it to true, or return E_FAIL if it is already true.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;You don&amp;rsquo;t even have to care about race conditions, because there aren&amp;rsquo;t any. Only the class object can perform the real initialization. And since no one else has an interface pointer yet, there can&amp;rsquo;t be a race.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The client side&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Creating a new CStuff has changed a little bit, because now we can&amp;rsquo;t use CoCreateInstance anymore. So construction is now done in 2 stages:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuffCreator&amp;gt; stuffClass;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = CoGetClassObject(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff), CLSCTX_ALL, NULL,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuffCreator), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;stuffClass);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//make a new stuff&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComBSTR stuffName = L&lt;span style="color:#a31515;"&gt;&amp;quot;Kato&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuff&amp;gt; newStuffUnk;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = stuffClass-&amp;gt;MakeMeAStuff(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;stuffName.m_str,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(GUID*)&amp;amp;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuff),&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(IUnknown**)&amp;amp;newStuffUnk);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It&amp;rsquo;s still very simple though. First we get the class object, and then we use the IStuffCreator interface to create the new CStuff.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Server lifetime management&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Everything works, hip hip hurray&amp;hellip; until you destroy the first CStuff instance, and then try to create another one. That is where it all goes pear shaped.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The problem is that we haven&amp;rsquo;t taken care of managing the lifetime of the server (the exe). The key issue here is the module lock reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Each COM module (exe or dll) has a global reference count to keep track of how many objects are &amp;lsquo;alive&amp;rsquo;. COM objects exist physically inside a DLL or EXE. So the EXE has to stay alive as long as there are living objects inside. Conversely, as soon as there are no living objects anymore, the EXE should shut down.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;What happens in our example is that CStuff raises the module ref count when it is created. And when the CStuff instance destroys itself, it lowers the module ref count. If you remember correctly, the class object itself uses CComObjectNoLock as its COM core. This means that its existence does not influence the module lifetime.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So when the CStuff instance destroys itself and lowers the module ref count, the ref count reaches 0 and the server EXE shuts down.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The client is unaware of this and tries to use the class object again. It still thinks it has a valid interface pointer, but the underlying class object is long gone and there will be a critical error in the client application.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;You might say &amp;lsquo;well duh, then don&amp;rsquo;t use CComObjectNoLock, doofus&amp;rsquo; but that has the opposite effect. The COM runtime will always have the interface pointer that was used for registering the class object with CoRegisterClassObject. This means that the class object would not destroy as long as the server lives. And the server would keep living as long as the class object was around. This is clearly not the answer.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;IExternalConnection to the rescue&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The key to solving this problem is a rarely used standard interface. IExternalConnection is an interface that can be used by an object to track how many external connections there are to itself. This is basically an alternative to the standard object reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 2 methods in this interface:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHODIMP_(DWORD) AddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD extconn, DWORD dwReserved); &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHODIMP_(DWORD) ReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD extconn,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;DWORD dwReserved,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;BOOL bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If a client requests any class object, the COM runtime will retrieve it. But before the interface pointer is released to the client, it will request some interfaces itself for housekeeping purposes. One of those interfaces is IExternalConnection.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If a client requests an interface pointer to a class object, the marshaller will call AddConnection when it hands out the pointer, and ReleaseConnection when the pointer is destroyed.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So all we have to do is to make sure that a call to AddConnection will increment the module lock count, and a call to ReleaseConnection releases the module lock count.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Implementing IExternalConnection&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you look in MSDN, you won&amp;rsquo;t find it. It is undocumented, but the ATL headers contain an implementation for IExternalConnection. It&amp;rsquo;s called IExternalConnectionImpl&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;To use it, we only have to change CStuffCreator so that it inherits from it, and add it to the COM interface map.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IStuffCreator,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;public&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; IExternalConnectionImpl&amp;lt;CStuffCreator&amp;gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComGlobalsThreadModel&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//removed irrelevant stuff&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BEGIN_COM_MAP(CStuffCreator)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuffCreator)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;COM_INTERFACE_ENTRY(IExternalConnection)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;END_COM_MAP()&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//IExeternalConnectionImpl&amp;lt;T&amp;gt; extension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;void&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; STDMETHODCALLTYPE OnReleaseConnection(&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; STDMETHODCALLTYPE OnAddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsFirstLock);&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//removed irrelevant stuff&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;That is really all there is to it. The default implementation does not modify the module lock count. But it has 2 extension points that we can override. So that&amp;rsquo;s what we do to make sure the module lock count is managed properly.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; STDMETHODCALLTYPE CStuffCreator::OnAddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsFirstLock)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_pAtlModule-&amp;gt;Lock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; STDMETHODCALLTYPE CStuffCreator::OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_pAtlModule-&amp;gt;Unlock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IExternalConnectionImpl&amp;lt;CStuffCreator&amp;gt;::OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bThisIsLastUnlock,&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The only special thing that still needs mentioning is that OnReleaseConnection delegates back to the default implementation in IExternalConnectionImpl. It does this because there is something that needs to be done when the last external connection is closed.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (bThisIsLastUnlock &amp;amp;&amp;amp; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoDisconnectObject(&lt;span style="color:blue;"&gt;static_cast&lt;/span&gt;&amp;lt;T*&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;)-&amp;gt;GetUnknown(), 0);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If the last connection closes, the class object needs to call CoDisConnectObject to destroy its marshalling stub. Now I could copy paste this code into my implementation of OnReleaseConnection, but it is simpler to just delegate back to the base class for stuff that needs doing anyway.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The result&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now that we have provided this implementation of IExternalConnection, the server EXE will stay alive until all CStuff instances are gone, and noone is using the class object anymore. Only then will the EXE terminate. &lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;CComClassFactory revisited&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you look at the interface implemented by CComClassFactory, you&amp;rsquo;ll notice that IExternalConnection is missing. And yet, server lifetime of CComClassFactory is managed correctly.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The reason for this is that the COM runtime treats IClassFactory class objects differently from other class objects. It will check if the class object supports IClassFactory. And if it does, it calls IClassFactory::LockServer to indicate that someone is using the class object. And it unlocks the class object when the class object reference is released again.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In a way, it uses the IClassFactory in almost the same way as it would use IExternalConnection. And in a way it is too bad that this functionality was included in IClassFactory directly, instead of making IClassFactory inherit from IExternalConnection. The reasons for this are lost in the mists of time. But whatever the reasons, this is why IClassFactory doesn&amp;rsquo;t need IExternalConnection. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, implementing a non standard class object is not so hard. As long as you have a basic understanding of the underlying COM principles, ATL takes care of all the dirty work.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And by using these techniques, we can implement COM objects that need initialization before they can safely be used by the client. The source code for this article is available under the MIT license as usual.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And again I&amp;rsquo;d like to add a thank you for Microsoft&amp;rsquo;s Tim Springfield and Amit Mohindra&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1673035" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.67.30.35/Stuff_5F00_V2.zip" length="24747" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Practical ATL: Understanding the class object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/02/10/practical-atl-understanding-the-class-object.aspx</link><pubDate>Tue, 10 Feb 2009 07:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1671098</guid><dc:creator>vanDooren</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1671098</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1671098</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/02/10/practical-atl-understanding-the-class-object.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In my previous article in this series, I explained how to create a simple COM server and implement a method that returns an enumerator object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;It was all done very easily, but the ATL wizards hide some of the things that you really ought to know for my next article. For starters: where is the class object?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The class object is the COM object responsible for creating new instances of the CStuff COM object that I demonstrated in a previous article. But we didn&amp;rsquo;t have to write any code for it, nor is it even visible&amp;hellip; so what&amp;rsquo;s up with that?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Some more on class objects&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The class object of a COM server is the object that is actually responsible handing out instances of the COM object. The class object is a COM object itself, but only 1 instance of it normally exists in a module (DLL or EXE) per defined COM object type.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;For example, the &amp;lsquo;Stuff&amp;rsquo; COM object that I implemented in my previous article uses the standard class factory with IClassFactory as the interface for handing out new CStuff instances.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The most important method in IClassFactory is &amp;lsquo;CreateInstance&amp;rsquo; which simply creates a new instance of the COM object and then passes an interface pointer back to the caller.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Normally, this process is invisible to the client application, because &amp;lsquo;CoCreateInstance&amp;rsquo; uses IClassFactory behind the scenes so that the client doesn&amp;rsquo;t have to bother with it.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;First it calls &amp;lsquo;CoGetClassObject&amp;rsquo; to get the class object for the requested COM object, and then it uses the IClassFactory interface of that class object to create a new instance. That instance is then passed to the caller, as an interface pointer of the type that was requested in the call to &amp;lsquo;CoCreateInstance&amp;rsquo;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I think it is safe to say that &amp;lsquo;IClassFactory&amp;rsquo; (or one of its relatives) is the interface on the class object of 99.99% of all COM objects that have a class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;The default class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;By default, CStuff uses CComClassFactory as its default class object. But looking at the declaration of CStuff, it is not immediately apparent how it does this.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;CStuff derives from CCoClass&amp;lt;T&amp;gt;, which has the macro DECLARE_CLASSFACTORY in its implementation.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;For EXE servers, this macro expands to DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory), which in turn expands to &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; ATL::CComCreator&amp;lt; ATL::CComObjectNoLock&amp;lt; ATL::CComClassFactory &amp;gt; &amp;gt; _ClassFactoryCreatorClass;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;DLL servers use CComObjectCached instead of CComObjectNoLock, but I don&amp;rsquo;t cover DLL servers in this article.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;As you can remember from the first article that featured CStuff, the C++ COM classes are missing the IUnknown core by default, because the implementation of that core depends on how we want to the object to behave.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This means we have to shove our class into a COM object to make it whole. For class objects, the CComObjectNoLock is most appropriate, because the lifetime of the object should not contribute to the lifetime of the server executable. Otherwise there would be a deadlock.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The server would start, and create the class object. And then the server would continue to live until the class object was destroyed. But since the COM runtime will always have a reference to the class object, the reference count would never reach zero, the class object would never be destroyed, and the server would never be able to shut down.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And finally, this class definition is shoved into a creator object which will help us by creating a properly initialized instance of the class object itself via its static CreateInstance function.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Associating the COM object C++ class with the class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;So the COM object C++ class has a typedef that identifies the class object type. But how does the executable use this fact?.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This is where things get a little hairy, and possibly start to make ominous squishy sounds &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;After the class declaration of CStuff, there is the innocuous line &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;OBJECT_ENTRY_AUTO(&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff), CStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The OBJECT_ENTRY_AUTO is a macro that expands to this:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#define&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; OBJECT_ENTRY_AUTO(clsid, &lt;span style="color:blue;"&gt;class&lt;/span&gt;) \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;selectany&lt;/span&gt;) ATL::_ATL_OBJMAP_ENTRY __objMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt; = {&amp;amp;clsid, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::UpdateRegistry, &lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;class&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;::_ClassFactoryCreatorClass::CreateInstance&lt;/span&gt;&lt;/b&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;, &lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;::_CreatorClass::CreateInstance&lt;/b&gt;&lt;/span&gt;, NULL, 0, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::GetObjectDescription, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::GetCategoryMap, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::ObjectMain }; \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;extern&lt;/span&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;C&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;allocate&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;ATL$__m&amp;quot;&lt;/span&gt;)) &lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;selectany&lt;/span&gt;) ATL::_ATL_OBJMAP_ENTRY* &lt;span style="color:blue;"&gt;const&lt;/span&gt; __pobjMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt; = &amp;amp;__objMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt;; \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;OBJECT_ENTRY_PRAGMA(&lt;span style="color:blue;"&gt;class&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Don&amp;rsquo;t worry if the sight of this code makes you nauseous. That&amp;rsquo;s normal. I highlighted the important parts&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;What it does is simple. It&amp;rsquo;s just how it does it that is ugly. It creates a map entry for the ATL innards of our server executable. In this map entry, it associates the static method for creating the class object with the static method for creating an object instance.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Creating the class object&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Now that the class object and the COM object are associated with each other, the next bit of code in the ATL headers is where the magic happens:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_OBJMAP_ENTRY* pEntry;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (m_pObjMap != NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pEntry = m_pObjMap;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; (pEntry-&amp;gt;pclsid != NULL &amp;amp;&amp;amp; hr == S_OK)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pEntry-&amp;gt;RegisterClassObject(dwClsContext, dwFlags);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pEntry++;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;When the ATL module initializes, it will iterate over all elements in the object map and register each one. And this registration process entails the following:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IUnknown* p = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (pfnGetClassObject == NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; S_OK;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT hRes = pfnGetClassObject(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pfnCreateInstance,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown),&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(LPVOID*) &amp;amp;p);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (SUCCEEDED(hRes))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hRes = CoRegisterClassObject(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;*pclsid, p, dwClsContext, dwFlags, &amp;amp;dwRegister);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (p != NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;p-&amp;gt;Release();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hRes;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you do a bit of spelunking in the headers, you&amp;rsquo;ll see that pfnGetClassObject is a function pointer that maps to _ClassFactoryCreatorClass::CreateInstance. So this code simply creates a new class object and registers it.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Again, this is specific to EXE servers. In DLL servers, the class object is created on demand in the DllGetClassObject function, which is called by CoGetClassObject if the COM server is a DLL.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Creating CStuff instances&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you look at the _ClassFactoryCreatorClass::CreateInstance, you&amp;rsquo;ll see that its first parameter is a void *. And the value that is passed in this parameter by the ATL module is the address of the static method for creating new object instances.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;_ClassFactoryCreatorClass::CreateInstance simply creates a new class object &amp;lsquo;p&amp;rsquo;, and then calls &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;p-&amp;gt;SetVoid(pv);&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt; to pass the aforementioned function pointer to the class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And the SetVoid method is no more complicated then this:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_CREATORFUNC* m_pfnCreateInstance;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I guess the original developer hadn&amp;rsquo;t had his morning coffee yet when he came up with this name. It manages to be 100% factually correct, while being 100% opaque at the same time. But it does the job.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;When the class object has to create a new instance, it simply does the following:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, &lt;span style="color:blue;"&gt;void&lt;/span&gt;** ppvObj)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// snip irrelevant code&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// snip irrelevant code&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hRes;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Providing a new class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Now that you understand how the class object plumbing is hooked up, it is easy to see how you can implement your own class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Remember how DECLARE_CLASSFACTORY_EX maps a class object to the _ClassFactoryCreatorClass typedef?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In C++, a typedef in a derived class can override a typedef in a base class. So even though the CCoClass&amp;lt;T&amp;gt; base class says that the _ClassFactoryCreatorClass maps to &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;ATL::CComCreator&amp;lt; ATL::CComObjectNoLock&amp;lt; ATL::CComClassFactory &amp;gt; &amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We can override this by simply putting &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;DECLARE_CLASSFACTORY_EX(CStuffCreator) &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In the declaration for CStuff. That&amp;rsquo;s really all there is to it. The macro magic takes care of the rest.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If changing the class object for a COM server is as trivial as adding a single line to your COM server C++ class, then why did I just write 4 pages of stuff?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I wrote all this because if I tell someone to use a macro to do something non-trivial, I want him or her to understand what is going on. There are already far too many programmers on this planet who do things without understanding what it is they do, or how it works. And I am not going to add some more by glossing over the details.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Of course, judging by the number of visitors on this corner of the internet that I call &amp;lsquo;home&amp;rsquo;, I stand little risk of doing so no matter how crappy I would write &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This article was originally part of my article on implementing a custom class object. But after I spent more than 3 pages on the previous explanation, I thought it would be best to put it in a separate article. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;A big thank-you goes to Jim Springfield of the Architects team within the developers division (I think) of Microsoft for taking the time to review this article for correctness, and to Amit Mohindra for helping my questions and articles reach the right people.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And you can find the demo project attached to this article under the MIT license.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1671098" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.67.10.98/Stuff_5F00_V2.zip" length="24747" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Getting started with ATL</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/20/getting-started-with-atl.aspx</link><pubDate>Tue, 20 Jan 2009 10:53:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1663592</guid><dc:creator>vanDooren</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1663592</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1663592</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/20/getting-started-with-atl.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I am currently working on some projects where I have to program a DCOM server. There are several reasons why it has to be DCOM and C++, instead of e.g. .NET remoting and C#.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The biggest pain (imo) about DCOM is that the technology stems from an era when the internet was no ubiquitous, and there were no huge forums filled with experts, or blogs by programming gurus and sites like codeproject.com There were newsgroups, but those were generally only used for specific problems.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There is a vast amount of concise information about everything you can do with the .NET framework. For DCOM there is &amp;hellip; a big dark void.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Granted, there are several resources out there. But if you look on sites like codeproject, you will find that most of the articles about DCOM and ATL are written before 2003. Most of the information out there will not cover the improvements that have been made to ATL (or DCOM) since the last 5 years.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And when looking into the more obscure corners of DCOM, there are some things that noone really likes to talk about because the documented semantics are so vague, and if you look into things like custom IMoniker implementation&amp;hellip; well&amp;hellip; that is a story for another day.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Understanding DCOM&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The most important thing with DCOM is that you understand the basics really well. I guess this is true for most things, but unlike other things like .NET, DCOM does not cut you any slack, and does not provide you with tons of helpful diagnostic information.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When I started with DCOM a couple of years ago, I first read &amp;lsquo;Essential COM&amp;rsquo; by Don Box. This is really the most excellent book on COM ever.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, this information becomes vitally important in the real world when you have to debug a problem, because no tool is going to tell you anything useful with DCOM related crashes.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Understanding ATL&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In the real world (unless maintaining legacy code) you use ATL to write COM clients or servers. Personally, I don&amp;rsquo;t like books that just tell me how to use technology XYZ. I like to understand the &amp;lsquo;why&amp;rsquo; and &amp;lsquo;how&amp;rsquo; too.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This is where I have to give big thanks to &amp;lsquo;ATL Internals, Second Edition&amp;rsquo;. It is one of the very few books on ATL that were written for VS2005, and it is still valid for VS2008. It is also an extremely well written book.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you are starting with ATL (or if you want to know &lt;i style="mso-bidi-font-style:normal;"&gt;how&lt;/i&gt; it works) buy this book. This book is very, very good, and will teach you a lot.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;What happens next?&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Over the next weeks / months I will probably write a couple of articles describing how to do specific things with ATL. One article that is nearly finished is about implementing and using IEnumString using ATL.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Not rocket science by any measure, but ATL is severely lacking in the area of easy-to-find, up-to-date and to-the-point examples. So I figured that there is still value in writing about the ancient art of circles and lollipops, even if many developers probably think COM and ATL are no longer worth bothering with.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Oh and I released some &lt;a href="http://msmvps.com/blogs/vandooren/archive/2007/04/08/the-ancient-art-of-circles-and-lollipops-part-2.aspx" title="http://msmvps.com/blogs/vandooren/archive/2007/04/08/the-ancient-art-of-circles-and-lollipops-part-2.aspx"&gt;win32 DCOM demo projects some time ago&lt;/a&gt;. They were interesting for me because making them taught me a lot about the raw DCOM stuff that you normally don&amp;rsquo;t see with ATL. But I&amp;rsquo;ve always found that it is always useful to know what makes the motor hum.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So while they are not terribly useful for practical purposes, they are well documented and they might be useful if you are working your way through &amp;lsquo;Essential COM&amp;rsquo;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1663592" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Found an interesting bug in the Visual Studio IDE</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/08/found-an-interesting-bug-in-the-visual-studio-ide.aspx</link><pubDate>Thu, 08 Jan 2009 07:18:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1659100</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1659100</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1659100</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/08/found-an-interesting-bug-in-the-visual-studio-ide.aspx#comments</comments><description>&lt;p&gt;I know, I know, ... .NET is all the rage, and DCOM is legacy technology, best not touched by up and coming programmers with good hair and sharp look, lest they appear &amp;#39;uncool&amp;#39; or even worse: &amp;#39;obsolete&amp;#39;.&lt;/p&gt;
&lt;p&gt;But some of us still use DCOM for a number of good reasons. And ATL takes much of the pain out of DCOM development. Unfortunately, the Visual Studio IDE doesn&amp;#39;t always cooperate. I made a simple MFC dialog client application, and then tried to add the ATL Server project that the client would connect to. VS was clearly concerned about my attempts to use DCOM instead of .NET, and decided to sabotage my attempts to do anything useful with this new ATL project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But luckily, I was able to figure it out and outsmart VS :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1659100" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Backing up event logs in their normal binary format</title><link>http://msmvps.com/blogs/vandooren/archive/2008/12/19/backing-up-event-logs-in-their-normal-binary-format.aspx</link><pubDate>Fri, 19 Dec 2008 13:15:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1657238</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1657238</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1657238</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/12/19/backing-up-event-logs-in-their-normal-binary-format.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Some time ago I was looking for a way to make backups of the eventlogs of our server, preferably without me ever having to do anything anymore &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This was not success. There are a couple of tools to make text exports from eventlogs. These have the disadvantage that they make the logs very large and unsuitable for looking at with the even viewer. As an added bonus, these are slow too (since every item has to be read individually).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;EventQuery.vbs is one of these tools and it is so dog slow that it is almost a crime that it has been included with Windows. Ever wanted to bring a domain controller slow to a crawl? Simple: Use EventQuery.vbs to export the security event log. That&amp;rsquo;ll do it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Anyway, I checked with my fellow MVPs, and there is no built-in (or free) tool to save event logs as binary event log files, so I gave up.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But then I accidentally discovered that there is a win32 API that exposes the event log functionality. And as luck would have it, I am a programmer and thus perfectly suited to make such a thing myself. It would have been trivial to make it at work, but I decided to do this at home so that I could share the code.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It is of course perfectly possible that such a free tool exists and I simply didn&amp;#39;t find it.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;The code&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code is simple, though the line count was increased by the desire to implement error handling.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; _tmain(&lt;span style="color:blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* computerName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* logName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* file = NULL;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//populate the variables, based on the input arguments&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(argc == 3)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;computerName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName = argv[1];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;file = argv[2];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;span style="color:blue;"&gt;if&lt;/span&gt;(argc == 4)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;computerName = argv[1];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName = argv[2];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;file = argv[3];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Usage();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Open the eventlog&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HANDLE hEventLog = OpenEventLog(computerName, logName);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(NULL == hEventLog)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tprintf_s(TEXT(&lt;span style="color:#a31515;"&gt;&amp;quot;Could not open eventlog %s on computer %s\n&amp;quot;&lt;/span&gt;),&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName, computerName);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PrintError();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//backup the event log to file&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FALSE == BackupEventLog(hEventLog, file))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tprintf_s(TEXT(&lt;span style="color:#a31515;"&gt;&amp;quot;Could not save eventlog to file %s\n&amp;quot;&lt;/span&gt;), file);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PrintError();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CloseEventLog(hEventLog);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CloseEventLog(hEventLog);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There is little to tell about the code. It can be invoked with either 2 or 3 command line arguments:&lt;/span&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The name of the computer of which the logs have to be backed up. (optional)&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The name of the event lot to back up&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The path of the file to which the event log needs to be saved.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The application opens the event log, and then makes the backup and closes the eventlog. If something goes wrong, the error code and error message are printed to the command line.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I thought about making the error handing a little more elegant (so that PrintError and CloseEventlog were not used multiple times in the code) but with only 2 function calls, the amount of error handling code would not diminish or be any better.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I left the PrintError function out of this blog because it doesn&amp;rsquo;t do anything exciting. It retrieves the error code and prints out the corresponding error message.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;What you need to know before using this tool&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I&amp;rsquo;ve been using this tool for a week now, and it is working splendidly, but there are a couple of things that aren&amp;rsquo;t mentioned in the MSDN documentation of the API.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The first is that the supplied path is absolute for the computer of which you are making an even log backup. So if the path is D:\app.evt, it will make the backup to D:\app.evt on the remote computer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The second thing you need to know is that providing a UNC name for the target file doesn&amp;rsquo;t really improve things all that much. Because what is happening under the hood is that it is not &lt;i style="mso-bidi-font-style:normal;"&gt;you&lt;/i&gt; who is making the backup.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The event log service is in charge of the event log files, and you are asking it to make a backup. And that is where it all goes pear shaped. The event log service runs with &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;LOCAL_SYSTEM credentials. This means that by default, it has no credentials that are valid on a remote computer. So you cannot make backup files in network locations, because the event log service of the remote computer has no privileges to access the location.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 2 exceptions to this rule. 1) the remote location is on the remote computer itself. 2) the remote computer is a backup domain controller.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It is a little known fact (I didn&amp;rsquo;t know it either) that LOCAL_SYSTEM on a domain controller is a domain administrative account that can pretty much do anything and everything on any domain computer, including the things that even a domain admin cannot.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I needed a convenient tool for making backups of event log files, and now I have one. Both the source and the binary are included as attachments. The source is available under the MIT license, and the exes are available for free to do with them what you want, &lt;span style="text-decoration:underline;"&gt;as long as it is understood that whatever you do with them is your responsibility, not mine&lt;/span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The eventtool_clr exe is something I made to create and delete event logs. I don&amp;rsquo;t think I blogged about it yet, but what it does is so simple it&amp;rsquo;s hardly worth mentioning. Have a look at the sources for more info.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The binary is for those who just want to use it and don&amp;rsquo;t care. The source is for those who&amp;rsquo;d rather not run an untrusted binary from some guy on the internet on their internal servers &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; The sources are simple enough to audit and compile.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;On a side note, The API to backup event logs is not exposed on the .NET api for event logs. I don&amp;rsquo;t know exactly why, but I suspect that it is because of the problems I mentioned. The API is confusing enough that it is really not fit for generic use. After all, you can&amp;rsquo;t backup to remote systems, and the path is absolute for the remote computer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I also didn&amp;rsquo;t want a .NET program, because for this type of thing, nothing beats the convenience and performance of a compiled binary that needs no runtime DLLs or external frameworks. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1657238" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.65.72.38/EvtLogTools.zip" length="65637" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Interesting blog post on the VC blog</title><link>http://msmvps.com/blogs/vandooren/archive/2008/10/30/interesting-blog-post-on-the-vc-blog.aspx</link><pubDate>Thu, 30 Oct 2008 11:09:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1652485</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1652485</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1652485</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/10/30/interesting-blog-post-on-the-vc-blog.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx"&gt;http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stephan blogs about new stuff in the upcoming C++ 0x standard. It&amp;#39;s quite length, but well worth a read.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652485" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Small bug in the MSDN documentation</title><link>http://msmvps.com/blogs/vandooren/archive/2008/10/09/small-bug-in-the-msdn-documentation.aspx</link><pubDate>Thu, 09 Oct 2008 06:02:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1650257</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1650257</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1650257</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/10/09/small-bug-in-the-msdn-documentation.aspx#comments</comments><description>&lt;p&gt;Hardly worth mentioning, but there is a minor bug in the documentation of fopen and its friends. The remarks section lists the open mode encoding for 16 bit unicode as UTF16-LE instead of UTF-16LE.&lt;/p&gt;
&lt;p&gt;As I said it is very minor, but if you use fopen, care about the documentation and have 5 minutes to spare, you can hop over to &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=374113" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=374113"&gt;my bug report on connect&lt;/a&gt; and add a vote.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1650257" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>How not to ask question on a forum</title><link>http://msmvps.com/blogs/vandooren/archive/2008/10/06/how-not-to-ask-question-on-a-forum.aspx</link><pubDate>Mon, 06 Oct 2008 06:29:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649846</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1649846</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1649846</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/10/06/how-not-to-ask-question-on-a-forum.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/2e693be9-a672-4f81-b729-42ad9aefcaa6" title="http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/2e693be9-a672-4f81-b729-42ad9aefcaa6"&gt;Here is another person who needs to learn some netiquette&lt;/a&gt; (emphasis mine).&lt;/p&gt;
&lt;p style="PADDING-LEFT:30px;"&gt;Hey,&lt;br /&gt;&lt;strong&gt;well, I will not describe my situation because it is not part of my question and has nothing directly to do with it and would only lead to false assumptions as it already did...&lt;br /&gt;&lt;/strong&gt;My question is ... &amp;lt;snip&amp;gt;&lt;br /&gt;&lt;strong&gt;Not that I am implying anything, but seeing that the discussion may drift to an entirely different topic directly, please do not return the question of why I am wanting to do this. I do know what I am doing and why I would need this&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Any help would be greatly appreciated.&lt;br /&gt;Regards,&lt;br /&gt;pd&lt;/p&gt;
&lt;p&gt;His question would have a much better chance of being answered if he&amp;#39;d recognised that the people answering questions are actual people. We are volunteers, doing this to help and because some questions are actually very interesting. Treating us like helpdesk personnel is not something that we generally appreciate.&lt;/p&gt;
&lt;p&gt;We sometimes spend a lot of effort to answer a complex question if&amp;nbsp;the situation is very interesting. Or perhaps because the issue is something advanced that might be helpful to ourselves one day. Denying us the interesting bits and treating us like&amp;nbsp;a bad&amp;nbsp;manager treats his serfs is more likely to cause the reaction &amp;#39;well, in that case figure it out on your own&amp;#39;.&lt;/p&gt;
&lt;p&gt;And apart from the fact that the motivation to answer has left me already, the thing with complex questions is that the devil is in the details. If you don&amp;#39;t tell us&amp;nbsp;exactly what you are trying to do, and which problem you are trying to solve, then how are we supposed to know a) what causes the problem, and b) how to solve it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;EDIT: I discovered after some digging that he had asked this question before, and the original&amp;nbsp;thread was closed by a moderator because it could be useful to malware authors. Personally I don&amp;#39;t agree with this decision. But the OP should have mentioned this in his new thread. That way we would have known something more. And it doesn&amp;#39;t change the fact that he should have described his problem more clearly.&lt;/em&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649846" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Programmer discovers that floating point numbers have a floating point</title><link>http://msmvps.com/blogs/vandooren/archive/2008/10/02/programmer-discovers-that-floating-point-numbers-have-a-floating-point.aspx</link><pubDate>Thu, 02 Oct 2008 05:05:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649143</guid><dc:creator>vanDooren</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1649143</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1649143</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/10/02/programmer-discovers-that-floating-point-numbers-have-a-floating-point.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I hang out in the MSDN forums on a regular basis, to see if there&amp;rsquo;re any questions that need answering. Usualy this is pretty unexciting, but every now and again, the asker really needs a reality check.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/6b48c8ad-6920-41ba-ba9b-ae2054a35bcf"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This thread&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; came up some time ago, and it refuses to die.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The first thing that stands out is the title itself : &amp;lsquo;&lt;b style="mso-bidi-font-weight:normal;"&gt;A very serious bug in MS Visual C++&lt;/b&gt;&amp;rsquo;. Sensationalist headlines like this almost always indicate a serious misunderstanding on the part of the author. It also indicates someone who is very, very sure of himself, because it excludes any possibility that he himself might be wrong.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The initial message itself was the classical example of &amp;lsquo;newbie discovers floating point numbers, it&amp;rsquo;s the end of the world as we know it&amp;rsquo;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you haven&amp;rsquo;t bothered following the link, this is his gripe:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double a=111.567,b=111,c;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c=a-b;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and you will receive&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //a=111.56699999999999&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //b=111.00000000000000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //c=0.56699999999999307&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //instead =&amp;gt; a=111.567, b=111, c=0.567;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Yawn&amp;hellip; another programmer who discovers that the floating point format does not guarantee fixed decimal correctness. The results are correct within the required precision of the floating point format, so all is well.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A is no 111.567 because it is a floating point number, and not a fixed point number. In any case, googling for &amp;lsquo;&lt;i style="mso-bidi-font-style:normal;"&gt;what every computer programmer should know about floating point&lt;/i&gt;&amp;rsquo; will get you a paper that explains this issue in detail.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The original poster also explains that he has tested with every compiler from VC6 to VC2008, and they are all wrong. That in itself should have been a clue to think twice before using such a preposterous title.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Various people tried to explain the problem, but to no avail. Here are a handful of quotes from the OP (who is building an ERP system...)&amp;nbsp;in the course of the discussion:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;color:#080808;font-family:Symbol;mso-bidi-font-size:9.5pt;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;span style="mso-list:Ignore;"&gt;&amp;middot;&lt;span style="font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;Industry standard ??? I am not agreeing with you. There are laws of mathematics which must be respected by all. I can not agree that 111,567 is equal to 111.56699999999999 because of simple reason that it is not equal.&lt;/span&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li style="background:white;margin:6pt 6pt 6pt 0cm;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;mso-outline-level:2;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;You cover me with theory. Thank you. But things are much simpler.&lt;/span&gt;&lt;/li&gt;
&lt;li style="background:white;margin:6pt 6pt 6pt 0cm;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;mso-outline-level:2;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;I think that something fundamental such as a declaration of fractional numbers and their actions should not be in so surrounded way. I think that the variables with floating point (&amp;#39;double&amp;#39;) are unusable at this time, because they do not always give accurate results. And I would like experts from Microsoft, which deal with these issues, in some way to offer basic solution to this problem.&lt;/span&gt;&lt;/li&gt;
&lt;li style="background:white;margin:6pt 6pt 6pt 0cm;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;mso-outline-level:2;" class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;All indicate the standard IEEE as a dogma. I am not familiar with the IEEE simply because I do not have time. But once the standard makes it impossible to use a certain type of fundamental variables and actions with them, maybe it is better to consider changes in the standard&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;But it gets even better! A second poster enters the discussion with the claim&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&amp;lsquo;I am absolutely astounded by two things here:&lt;br /&gt;1. That this math bug is still floating around (I remember when it was a CPU issue)&lt;br /&gt;2. That people here claim that it is not a bug in c++ in VS2003 or later&amp;rsquo;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;Someone then explains that his SUN stations give the same results, just to indicate that this problem has nothing to do with compiler errors (or CPU dependency) whatsoever.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;But it wasn&amp;rsquo;t meant to be. What did the second poster reply?&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&amp;lsquo;Thanks for testing it for me on the SPARC system.&lt;br /&gt;Perhaps it is some bizarre feature of hardware-based floating point present in modern CPUs?&amp;nbsp; This may account for why similar code compiled on older compilers (VS6) (who don&amp;#39;t have modern FCPU knowledge) yields expected results.&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;&amp;hellip;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="font-size:9.5pt;color:#080808;font-family:Verdana;"&gt;It&amp;#39;s a&amp;nbsp; bit amusing when the system can&amp;#39;t even handle a result with one decimal place!&amp;rsquo;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Ah well.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If people are misguided, you can do your best to make them see. But if they want nothing to do with &amp;lsquo;reality&amp;rsquo;, then you can&amp;rsquo;t force them to understand.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;After all, the powers of reason are futile in face of the powers of persuasion that allow someone to think every CPU, compiler and engineer / programmer / scientist in existence is wrong.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649143" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>My latest article in NTInsider</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/26/my-latest-article-in-ntinsider.aspx</link><pubDate>Fri, 26 Sep 2008 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1648864</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1648864</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1648864</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/26/my-latest-article-in-ntinsider.aspx#comments</comments><description>&lt;p&gt;A bit late perhaps, but my latest article on API development got published in the NTInsider (owned by &lt;a href="http://www.osronline.com" title="http://www.osronline.com"&gt;OSR Online&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The online version can be found &lt;a href="http://www.osronline.com/article.cfm?article=521" title="http://www.osronline.com/article.cfm?article=521"&gt;here&lt;/a&gt;. It requires free registration.&lt;/p&gt;
&lt;p&gt;I know that at least 2 people have read it completely, because that is the number of mails I got to tell me I missed something.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the code example at the bottom, I acidentally switched the names of fooA and fooB in the declaration. Doh!&lt;/li&gt;
&lt;li&gt;That same code, compiled for a 64 bit platform, gives a &lt;a href="http://support.microsoft.com/kb/835326" title="http://support.microsoft.com/kb/835326"&gt;linker warning&lt;/a&gt;. I don&amp;#39;t know how I missed that. This code was made using VS2005, so one of two things could have happened: VC2005 didn&amp;#39;t report the warning (unlikely), or I only checked the compilation in detail, and then only checked if the function was exported without checking if there were linker warnings. It&amp;#39;s probably the latter.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;#39;ll see if I can get these errata published. But at least now I know that people actually read my articles and use the code. Well, at least one person is using the code :) I&amp;#39;ll have to make an extra effort next time to verify that a) I didn&amp;#39;t make a stupid type, and b) There are no warnings anywhere.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1648864" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Driver+programming/default.aspx">Driver programming</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category></item><item><title>C++ keyword of the day: export</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/24/c-keyword-of-the-day-export.aspx</link><pubDate>Wed, 24 Sep 2008 10:48:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1648758</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1648758</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1648758</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/24/c-keyword-of-the-day-export.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;The export keyword is a bit like the Higgs boson of C++. Theoretically it exists, it is described by the standard, and noone has seen it in the wild. :)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;Before I get flamed to hell and back: that last part is not entirely true. There is 1 C++ compiler front-end in the world which actually supports it. That is the one made by EDG (Edison Design Group). This is used by Comeau which claim to have the only compiler that is 100% standards compliant and Borland (for which the support of export is a bit vague). I heard that the Intel compiler shipped with it, but I don&amp;rsquo;t know if this is true or not.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;What&amp;rsquo;s all the fuss about?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;It seems a bit strange that a language should contain a keyword that all compiler makers refuse to implement. Comeau has some &lt;a href="http://www.comeaucomputing.com/iso/promises.html" title="http://www.comeaucomputing.com/iso/promises.html"&gt;interesting content here&lt;/a&gt;&amp;nbsp;as does &lt;a href="http://en.wikipedia.org/wiki/Export_(C%2B%2B)#Standards_compliance" title="http://en.wikipedia.org/wiki/Export_(C%2B%2B)#Standards_compliance"&gt;Wikipedia&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;The reason that I believe &amp;#39;export&amp;#39; has never really taken off is that is seems to be an significant effort to implement it, combined with the fact that is doesn&amp;#39;t achieve all that much. The export keyword allows a C++ programmer to declare a template class in a header, and then provide the implementation separately in a cpp file. This is the normal C++ way of doing things. Unfortunately, there&amp;#39;s a snag.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;Template class implementations cannot be compiled on their own. Template code itself is meaningless without specification of template arguments. Thus it is that a compiler doesn&amp;#39;t know what to do with an implementation until the template class is used somewhere. At that point the template arguments will be known, and the compiler can compile the template class.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;Since the template is only compiled then, the easiest thing to do would be to do what most compilers do now: demand that the implementation is in scope when it is used somewhere. I.e. the implementation has to be put in a header file, and that header file has to be included by the source file that is being compiled. the reason for this is that the compiler would simply not know where to look for it if the implementation was in a cpp file somewhere.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;The export keyword would solve this by telling the compiler &amp;#39;Look somewhere else for the implementation&amp;#39;. The compiler would then have to compile the implementation for that class, and save the object code somewhere for that combination of template arguments.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;"&gt;The export keyword sounds like a great thing, but it doesn&amp;#39;t solve that many problems.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Separation of interface and implementation&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;The separation of interface and implementation is one of the cornerstones of C++ philosophy. The traditional way is to have the declaration in a header file, and then put the implementation in a cpp file.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;Since a template implementation cannot be compiled anyway, we could just as well put it in a header file.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;And then we could also make 1 header file with just the declarations, and underneath that include the header file(s) containing the implementation. The nice thing is that you can then put specializations in different headers to keep the code comprehensible.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;This way we keep true to the principle of separation without needing the &amp;lsquo;export&amp;rsquo; keyword&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Distribution&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;You can&amp;rsquo;t distribute template classes in a binary form, no matter whether export is supported or not.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;Because templates cannot be compiled on their own, you cannot link them into a static or dynamic library. The only thing you can do is to distribute the source code.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;Templates are distributed as source code. The export keyword cannot do anything about that. And if you want to distribute templates, what are you going to do? You can develop your classes using &amp;lsquo;export&amp;rsquo;, but then they will be usable only by a very limited subset of compilers.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;If you develop your classes as if &amp;lsquo;export&amp;rsquo; doesn&amp;rsquo;t exist, then they can be used by all compilers.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;Of course you could do both, and use ugly macro magic to construct your code in such a way that would leave the choice to the client programmer. Some people do this. But that is kind of &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;ugly and time consuming. Furthermore, it&amp;rsquo;s not like it gets you any more clients, because they will be able to use your code in any case.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Compiler performance&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;It is true that our scheme of using header files is less efficient than using the export keyword. Without &amp;lsquo;export&amp;rsquo;, a template is compiled whenever it is used. You can mitigate this somewhat by including commonly used templates in a precompiled header file. But the impact will only be somewhat lessened.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;And whenever an implementation detail changes, every source file which includes the template has to be recompiled. This can be a real pain in large projects.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;&amp;lsquo;export&amp;rsquo; is facing the chicken or the egg dilemma.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;&amp;lsquo;export&amp;rsquo; is neglected by most compiler vendors because it is not an important language feature -&amp;gt; You cannot use it in code that has to be portable (which is ironic, since it is a standard keyword) -&amp;gt; it is not used in many scenarios -&amp;gt; there is no large codebase depending on support for &amp;lsquo;export&amp;rsquo; -&amp;gt; there is little incentive for compiler vendors to start supporting it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:7.5pt;color:black;font-family:Verdana;mso-bidi-font-size:12.0pt;"&gt;Make no mistake: I would appreciate it if I could use &amp;lsquo;export&amp;rsquo;, if only because it allows me to organize my template implementations in a standard manner, but I don&amp;rsquo;t think it&amp;rsquo;ll happen soon. &lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1648758" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>References in C++ are not necessarily safe</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/17/references-in-c-are-not-safe.aspx</link><pubDate>Wed, 17 Sep 2008 12:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1647968</guid><dc:creator>vanDooren</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1647968</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1647968</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/17/references-in-c-are-not-safe.aspx#comments</comments><description>&lt;p&gt;People who are new to C++ sometimes have the mistaken idea that using references instead of pointers makes your code safe. People who have been programming a bit longer know this is anything but the case. References are just semantic sugar coated pointers. &lt;/p&gt;
&lt;p&gt;I&amp;#39;ll explain in more detail with a couple of examples. They use this pretty simple class A. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;struct&lt;/span&gt; A&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &amp;amp;I;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;A(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &amp;amp;i) : I(i)&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;} &lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; print(&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;)&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;cout &amp;lt;&amp;lt; I &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;};&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;When A is instantiated, the constructor takes a reference to an integer and uses it to initialize an internal integer reference. The print method simply prints the value of that integer. &lt;/p&gt;
&lt;h2&gt;Case 1 &lt;/h2&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; * i= &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;(32);&lt;br /&gt;A a(*i);&lt;br /&gt;*i = 43;&lt;br /&gt;a.print();&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;delete&lt;/span&gt; i;&lt;br /&gt;a.print();&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;I create a new integer value on the heap and I initialize a pointer with its address. I then create a new instance of A, and pass the newly created integer by reference. a initializes its own internal reference with the address of that integer. And indeed, if I assign a value to that integer and then print a&amp;#39;s internal reference, the values match. &lt;/p&gt;
&lt;p&gt;But what happens if that integer is deleted from the heap? It depends. The behavior is undefined. The next read from a.I could result in a bad value or an application crash. But in any case, it is not safe. &lt;/p&gt;
&lt;p&gt;You might argue that I am purposely using pointers to cause problems, but in a large application, you won&amp;#39;t know how and where your objects will be created. This could happen. &lt;/p&gt;
&lt;h2&gt;Case 2 &lt;/h2&gt;
&lt;p&gt;A second case is much more innocuous. It uses no visible pointers. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;vector&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; v;&lt;br /&gt;v.push_back(42);&lt;br /&gt;A b(v[0]);&lt;br /&gt;v[0] = 43;&lt;br /&gt;b.print();&lt;br /&gt;v.pop_back(); &lt;span style="color:#008000;"&gt;//remove that element from the container&lt;br /&gt;&lt;/span&gt;b.print();&lt;br /&gt;v.push_back(2); &lt;span style="color:#008000;"&gt;//put something else in the same location&lt;br /&gt;&lt;/span&gt;b.print();&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Instead of dynamically allocation memory myself, I put an integer in a vector and then feed a reference to that element into an instance of A. This new instance (b) is now using the location of an element in a vector as an internal reference. &lt;/p&gt;
&lt;p&gt;The thing with vectors is that they normally have more capacity than elements. This is because you don&amp;#39;t want the vector to allocate more space for every element that gets inserted. Likewise, you are not going to do a deallocation with each element that gets removed. &lt;/p&gt;
&lt;p&gt;Because of this, when that element is removed, the physical space is still there. A read from that location is not immediately going to trigger a crash. Instead, the program will keep on running, but with bad data instead. Or maybe not, if that element was at the threshold of triggering a deallocation. With bugs like this, you never know what will happen. &lt;/p&gt;
&lt;h2&gt;Case 3 &lt;/h2&gt;
&lt;p&gt;There is an even more interesting option. I am not going to write a repro case for it, but consider the following: I create multiple instances of A, giving them each a reference to an integer that is located on the stack, and I pass those instances of A as pointers to newly created threads, to be used there. &lt;/p&gt;
&lt;p&gt;Meanwhile, the stack on which the integers are located is unwound. What happens next? &lt;/p&gt;
&lt;p&gt;Again, it depends. Probably the stack gets stomped. Or perhaps only the data will be corrupted. Again, what happens is unknown. And I don&amp;#39;t say that this design pattern is a good one. It isn&amp;#39;t. But given certain constraints, it might just be an approach for solving a specific problem (though perhaps not the best one). &lt;/p&gt;
&lt;h2&gt;Conclusion &lt;/h2&gt;
&lt;p&gt;By now, anyone should be convinced that using references do not protect your application against design mistakes. &lt;/p&gt;
&lt;p&gt;The only time your references are really safe is if:&lt;br /&gt;a) your application is single threaded, and there is no asynchronous code executed anywhere, and&lt;br /&gt;b) your classes don&amp;#39;t store references anywhere.&lt;/p&gt;
&lt;p&gt;Outside of those constraints, references don&amp;#39;t guarantee anything more than pointers would. The only guarantee you have with references is that at some point in time, there was an object of the correct type at the specified location, and it was not NULL. Probably.&lt;/p&gt;
&lt;p&gt;If someone is actively trying to subvert your code, you can&amp;#39;t even be sure of that. But since there is nothing you can do about that, you might as well use references because they make your life easier, and are better than raw pointers when it comes to preventing honest mistakes.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647968" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>How DLL exports really work</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/12/how-dll-exports-really-work.aspx</link><pubDate>Fri, 12 Sep 2008 10:42:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1647589</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1647589</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1647589</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/12/how-dll-exports-really-work.aspx#comments</comments><description>&lt;p&gt;I found this list of article on &lt;a target="_blank" href="http://blogs.msdn.com/oldnewthing" title="http://blogs.msdn.com/oldnewthing"&gt;Raymond&amp;#39;s blog&lt;/a&gt;. Raymond&amp;#39;s blog is one of the more interesting for programmers who use native APIs because he often touchs on things that are not documented, but interesting to know if you care about how things really work under the hood.&lt;/p&gt;
&lt;p&gt;These links all point to information that goes into DLL importing and exporting, and how it is implemented under the hood. Very interesting stuff.&lt;/p&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/14/665669.aspx"&gt;How were DLL functions exported in 16-bit Windows?&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/17/668284.aspx"&gt;How were DLL functions imported in 16-bit Windows?&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/18/669668.aspx"&gt;How are DLL functions exported in 32-bit Windows?&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/19/671238.aspx"&gt;Exported functions that are really forwarders&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/20/672695.aspx"&gt;Rethinking the way DLL exports are resolved for 32-bit Windows&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/21/673830.aspx"&gt;Calling an imported function, the naive way&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/24/676669.aspx"&gt;How a less naive compiler calls an imported function&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/25/677878.aspx"&gt;Issues related to forcing a stub to be created for an imported function&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/26/679044.aspx"&gt;What happens when you get dllimport wrong?&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/27/679634.aspx"&gt;Names in the import library are decorated for a reason&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/01/12/57833.aspx"&gt;The dangers of dllexport&lt;/a&gt;&lt;/li&gt;
&lt;p&gt;Another thing which may be useful if you haven&amp;#39;t read it yet are Michael Grier&amp;#39;s articles on the NT DLL loader &lt;a href="http://blogs.msdn.com/mgrier/archive/2005/06/28/433707.aspx" title="over here"&gt;&lt;span style="color:#000000;"&gt;over here&lt;/span&gt;&lt;/a&gt;. I&amp;#39;ve &lt;a target="_blank" href="http://msmvps.com/blogs/vandooren/archive/2006/10/08/What-every-programmer-should-know-about-DLL-loading.aspx" title="http://msmvps.com/blogs/vandooren/archive/2006/10/08/What-every-programmer-should-know-about-DLL-loading.aspx"&gt;blogged about&lt;/a&gt; those articles before. Michael is one of the project leaders who maintained the NT DLL loader for some time.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647589" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category></item><item><title>Stuck on stupid</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/10/stuck-on-stupid.aspx</link><pubDate>Wed, 10 Sep 2008 20:31:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1647171</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1647171</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1647171</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/10/stuck-on-stupid.aspx#comments</comments><description>&lt;p&gt;It happens to every programmer. It doesn&amp;#39;t happen often, but it does happen to everyone. You are looking at a piece of code or some debugging output, scratching your head and thinking &amp;#39;This is impossible&amp;#39;. It&amp;#39;s probably only 10 or 20 lines of code or text, and you&amp;#39;ve looked carefully at every line at least a dozen times over the last hour. &lt;/p&gt;
&lt;p&gt;Every line makes sense and seems to mean exactly what you think it means, every word is in place, every semicolon is accounted for, and yet the sum of those lines is something completely unlike what you think it should be. &lt;/p&gt;
&lt;p&gt;What makes matters even worse is that you just know that you are missing something obvious; something that anyone else would see after looking at the issue for less than 5 seconds. Maybe someone is even explaining the issue to you and you still don&amp;#39;t get it. &lt;/p&gt;
&lt;p&gt;Well, I had such a moment just this weekend. &lt;/p&gt;
&lt;p&gt;I was working on some C++ code that involved friend functions and streams. I&amp;#39;ve never done much with streams in C++, and never done anything with friends. Basically, friend declarations allow e.g. class A to specify that class B is allowed to access its private variables. Hence the joke: in C++, your friends can see your privates. I&amp;#39;ve never used it in a design, because if other classes need access to private data, the design is probably wrong. &lt;/p&gt;
&lt;p&gt;There are some exceptions, where it can be extremely useful. One of these cases is if you have to create a serialization function that can serialize and deserialize an object. That function would need access to the private data to efficiently reconstruct the object, but you don&amp;#39;t want any other functions or classes to have the same privilege. &lt;/p&gt;
&lt;p&gt;In my case, I had a template class that I wanted to reconstruct from a generic iostream. I implemented a global function that performed the reconstruction, but despite my friend declaration that gave istream access, the compiler didn&amp;#39;t agree. This is what my code boiled down to: &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;friend&lt;/span&gt; istream;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;istream&amp;amp; &lt;span style="color:#0000ff;"&gt;operator&lt;/span&gt; &amp;gt;&amp;gt;(istream&amp;amp; is, A &amp;amp;a)&lt;br /&gt;{&lt;br /&gt;is &amp;gt;&amp;gt; a.i; &lt;span style="color:#008000;"&gt;//error C2248: &amp;#39;A::i&amp;#39; :&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;//cannot access private member declared in class &amp;#39;A&amp;#39;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; is;&lt;br /&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I looked at it for a long time, read the &amp;#39;friend&amp;#39; documentation in MSDN, consulted my copy of &amp;#39;The C++ programming language, 3ed&amp;#39;, asked a fellow MVP to explain it to me, and I still didn&amp;#39;t get it. I reasoned: &amp;#39;I just gave istream access to A::I, so WTF is the problem&amp;#39;. &lt;/p&gt;
&lt;p&gt;In this case, the solution was really a &amp;#39;duh&amp;#39; moment. Yes, istreams have access to A. But &amp;ndash; and this is the whole issue &amp;ndash; it is not the istream doing the accessing. The istream accesses an integer by reference; an integer that was retrieved by the global operator &amp;gt;&amp;gt; function. My code was functionally equivalent to: &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt;istream&amp;amp; &lt;span style="color:#0000ff;"&gt;operator&lt;/span&gt; &amp;gt;&amp;gt;(istream&amp;amp; is, A &amp;amp;a)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &amp;amp;temp = a.i; &lt;span style="color:#008000;"&gt;//error C2248 &lt;br /&gt;&lt;/span&gt;is &amp;gt;&amp;gt; temp;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; is;&lt;br /&gt;}&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;And that is pretty obviously wrong. By writing is &amp;gt;&amp;gt; a.i, I lulled myself into believing it was &amp;#39;is&amp;#39; who did the access, while in reality it was someone else. &lt;/p&gt;
&lt;p&gt;As I said already: this was one of those &amp;#39;Aaargh&amp;#39; moments where I just seemed to be stuck on &amp;#39;stupid&amp;#39;. Ah well. Live, learn, and have more coffee next time &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt; Glad this doesn&amp;#39;t happen every day, week, or month.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1647171" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Regex bug in VC2008 SP1 TR1 library</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/04/small-regex-bug-in-vc2008-sp1-tr1-library.aspx</link><pubDate>Thu, 04 Sep 2008 09:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1646721</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1646721</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1646721</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/04/small-regex-bug-in-vc2008-sp1-tr1-library.aspx#comments</comments><description>&lt;p&gt;Yesterday I tracked down a bug in the TR1 regex library that is shipped with VS2008 SP1.&lt;/p&gt;
&lt;p&gt;If you use regexes, then the regex a| will cause an exception to be thrown because of supposedly illegal syntax. For example you could use (a|) in a regular expression to indicate that a string contains at a certain point either a or nothing.&lt;/p&gt;
&lt;p&gt;There are better ways to do this of course, and I&amp;#39;ve changed the problematic regex already, but it should have worked.&lt;/p&gt;
&lt;p&gt;I checked the .NET regexes, and they accept this syntax. .NET regex follows the &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf" title="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf"&gt;ECMAScript syntax&lt;/a&gt;, which specifies pretty unambiguously in section 15.10.1 (Thanks Igor for helping me identify the correct section) that the alternative operator should accept empty sections.&lt;br /&gt;The &lt;a href="http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2003/n1429.htm#syntax_discussion" title="http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2003/n1429.htm#syntax_discussion"&gt;TR1 proposal&lt;/a&gt; also specifies that ECMAScript is used, so it should accept this syntax.&lt;/p&gt;
&lt;p&gt;If you use TR1 regexes, take a minute of your time to vote for &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365994" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365994"&gt;this bugreport on connect&lt;/a&gt; so that they fix it in the next SP / release.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1646721" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Extending a native C++ project with managed code</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/03/extending-a-native-c-project-with-managed-code.aspx</link><pubDate>Wed, 03 Sep 2008 09:59:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1646601</guid><dc:creator>vanDooren</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1646601</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1646601</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/03/extending-a-native-c-project-with-managed-code.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;One question that comes up from time to time in the newsgroups is &amp;lsquo;I have a native C++ project and I want to extend it with Managed code (e.g. Windows Forms). What do I do?&amp;rsquo;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;The answer is not so complex. It is fairly easy to extend native projects with managed code. In this article I&amp;rsquo;ll explain how.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:medium;color:#17365d;font-family:Calibri;"&gt;What NOT to do&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;To quote &lt;/span&gt;&lt;a href="http://www.gregcons.com/kateblog/"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Kate Gregory&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; &amp;lsquo;In the name of all that is good and right: Do not set /CLR for the entire project&amp;rsquo;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;/CLR tells the compiler that it should compile a source file as C++/CLI code in which it finds both native and managed C++ code. Theoretically you could specify this for the whole project, but this has some serious consequences.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Apart from the fact that it is possible for the compiled output size to explode, there can be significant problems with COM and CRT initialization. I am no interop expert in the matter like &lt;/span&gt;&lt;a href="http://www.heege.net/blog/default.aspx"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Marcus Heege&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; or Kate, but I am willing to take their word for it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Furthermore, your existing project is possibly validated by QA en unit tested 7 days from Sunday. You don&amp;rsquo;t want to travel that road again if you can prevent it.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:medium;color:#17365d;font-family:Calibri;"&gt;What to do&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;You want to add managed stuff to your project while impacting the rest of the code as little as humanly possible. To achieve this you have to compartmentalize the managed stuff and give it a native interface that you can use in the native parts of you projects without any hassle.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;I think I can best explain this with a practical example.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;For the sake of this example I have a native DLL project that exports a function that returns an integer value. Perhaps this function got that integer value previously through an MFC interface, and now that value has to come from a Windows Forms interface.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Add the windows form to your project&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;This is the first and also the easiest step of the process. Rightclick your project and select &amp;lsquo;Add&amp;hellip;-&amp;gt;New Item&amp;rsquo; and select &amp;lsquo;UI-&amp;gt;Windows Form&amp;rsquo; in the Visual C++ dialog.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;You will then get a message box, telling you that your project will be converted to a managed project. Here you click &amp;lsquo;yes&amp;rsquo;. Even though you don&amp;rsquo;t want to compile your project with /clr, Visual Studio itself needs to know that you are doing managed stuff in your project. This is not necessary for compiling your project, but if you want to have the benefit of working with the forms designer and other .NET related things, then it would be a good idea. And you cannot add the form if you choose &amp;lsquo;No&amp;rsquo; so it&amp;rsquo;s not like you have much choice anyway.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Now you have a .NET Windows Form in your code. You can verify the file specific settings if you want, but the cpp file will be compiled with the /clr flag set, and without the use of precompiled headers. Not using precompiled headers is important, because the default precompiled header is compiled without /clr set, and this would lead to conflicts.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Of course, if you need to, you can create a copy of StdAfx.h/cpp cpp files called &amp;lsquo;StdAfxClr.h/cpp&amp;rsquo; add them to your project, and configure them to create a managed precompiled header, which you could then use for all files that are compiled with /clr. This is not necessary for small projects, but it could be a useful optimization in large projects.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="color:#17365d;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;The interface layer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;At this point you can compile and link the entire project, but your native code isn&amp;rsquo;t yet using the new managed functionality. And because the native code will not be compiled with /clr, it will never do so. In order to make that happen, you will need a thin layer between the native and managed code. This layer will have a native C or C++ interface which can be called by the native code, and a managed implementation that will do all the .NET stuff.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;In our example, the interface is 1 simple C style function in Interface.h:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoManagedStuff(&lt;span style="color:blue;"&gt;void&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;And this function has a simple implementation in Interface.cpp:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoManagedStuff(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DemoForm ^df = &lt;span style="color:blue;"&gt;gcnew&lt;/span&gt; DemoForm();&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;df-&amp;gt;ShowDialog();&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; df-&amp;gt;Value;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Interface.h and Interface.cpp are 2 new files that you have to add to your project. You have to manually configure the cpp file to be compiled with /clr, and to not use precompiled headers.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;As you can see, the interface layer provides a clean native interface for the managed stuff that you want your code to perform. Of course, you are not limited to C style interfaces. You can also work with classes and make classes with a native interface and a managed implementation. But there are a couple of issues that you need to be aware of. If you want to go there, then it would be a good idea to read &lt;/span&gt;&lt;a href="http://www.gotw.ca/publications/C++CLIRationale.pdf"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;the paper written by Herb Sutter&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; which explains the rationale behind C++/CLI, as well as some of the limitations and pitfalls.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Actually, reading that paper is a good idea for anyone working with C++/CLI who also cares about understanding what is actually going on behind the scenes.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Using the interface layer&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;All the hard work is done. Now you can simply include Interface.h in your native code files, and call &amp;lsquo;DoManagedStuff&amp;rsquo; where appropriate.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#include&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;stdafx.h&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;br /&gt;#include&lt;/span&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;InterfaceLayer.h&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoFoo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; DoManagedStuff();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;As you can see, extending native code with managed code is not so hard. At least, it isn&amp;rsquo;t if you maintain a clean break between managed and native code. If you cannot do this, things might become more difficult. For example, using .NET controls on an MFC dialog, or using .NET remoting in a native COM project are things that can be much more tricky.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Another thing you should be aware of is that not all compiler switches can be used in conjunction with the /clr&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;switch. The compiler will inform you if it detects this. The combinations which are not allowed are documented, and can be found in the documentation of the /clr switch itself.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;This post was not meant to be an exhaustive how-to to those complex scenarios, but instead an explanation behind the basic ideas.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;The demo project for this article can be downloaded under the MIT license as usual. &lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1646601" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.64.66.01/DemoDll.zip" length="18800" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Fun with templates: parsing command line arguments</title><link>http://msmvps.com/blogs/vandooren/archive/2008/08/14/fun-with-templates-parsing-command-line-arguments.aspx</link><pubDate>Thu, 14 Aug 2008 10:17:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1644623</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1644623</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1644623</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/08/14/fun-with-templates-parsing-command-line-arguments.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;One of the things that everyone has to do sooner or later is parsing command line arguments into program variables. Even the most trivial command line application needs some input variables to tell it what to do.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;One of the things in which C and C++ are lacking is a unified approach to command line arguments. This allows anyone to do what he wants, but unfortunately it also forces everybody to figure it out for himself.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I have done this several times, and tried several approaches. My last projects all needed moderately complex command line configurations, so I finally solved this problem in a reusable way. Originally I used the boost template library for this (&lt;/span&gt;&lt;a href="http://www.boost.org/"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;www.boost.org&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;). Specifically, I used regular expressions. But now that VS2008 SP1 is out, I can use the TR1 library to do this for me.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;What does a command line argument look like&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The exact syntax doesn&amp;rsquo;t matter because we are using regular expressions. What is important is that the identifier and the value are recognized by the shell to belong together.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The only way to do this is of course to make sure that they are in the same string. For example, such command line arguments can look like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="font-size:small;"&gt;-val:12.5&lt;br /&gt;/text=blabla&lt;br /&gt;-file=&amp;rdquo;C:\Documents and Settings\me\desktop\article.doc&amp;rdquo;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It really doesn&amp;rsquo;t matter. As long as all the information is recognized as 1 argument, it&amp;rsquo;s fine. If the value contains spaces, you need to use quotes so that the shell will not treat&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="font-size:small;"&gt;-file=&amp;rdquo;C:\Documents and Settings\me\desktop\article.doc&amp;rdquo;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;as 3 arguments.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Requirements&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The requirements for my solution are as follows:&lt;/span&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;1 function which can take a command parameter and a regular expression, and which can parse any given type (bool, int, string, &amp;hellip;) from the parameter, according to the specified regex.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The function should be able to handle string and wstring parameters.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It should be able to put values into regular data types, as well as into TriStateValue template types (see here &lt;/span&gt;&lt;a href="http://msmvps.com/blogs/vandooren/archive/2007/10/11/fun-with-templates-implementing-a-tri-state-value.aspx"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;http://msmvps.com/blogs/vandooren/archive/2007/10/11/fun-with-templates-implementing-a-tri-state-value.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; for more info).&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The function should return a bool to notify the user if the argument was parsed.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The part of the regex that identifies the actual value has to be captured. I.e. it has to be enclosed between ( ) symbols.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;First attempt&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The first version of such a function was ready pretty rapidly.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; pattern,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; arg,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T&amp;amp; value)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::smatch matches;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;( !std::tr1::regex_search(arg, matches, pattern))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::istringstream iss((string) matches[1]);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; ! (iss &amp;gt;&amp;gt; std::dec &amp;gt;&amp;gt; value).fail();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The function takes a regex and an argument. The value type is a template type which allows the user to use it for any type. The type itself can be inferred at compile time. I.e. the user does not have to explicitly specify the template type using brackets.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A string stream is used for getting the value out of the stream. This is very handy because this way, the text to value conversion has no dependency on the value type. By using the string stream, the function remains generic.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This function has an overload that uses a TriStateVal type for the resulting value.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; pattern,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; arg,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;TriStateVal&amp;lt;T&amp;gt;&amp;amp; value)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::smatch matches;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;( !std::tr1::regex_search(arg, matches, pattern))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::istringstream iss((string) matches[1]);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T val;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;((iss &amp;gt;&amp;gt; std::dec &amp;gt;&amp;gt; val).fail())&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;value = val;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The TriStateVal type allows the user of that value to know whether it had been assigned or not. Unfortunately, there is no support yet for streaming directly into a TriStateVal type, so I have to use a temporary value first.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, these 2 functions work for strings. What about wstring? Well, for wstring we need another 2 overloads.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::wregex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; pattern,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::wstring &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; arg,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T&amp;amp; value)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::tr1::wregex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; pattern,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;std::wstring &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; arg,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;TriStateVal&amp;lt;T&amp;gt;&amp;amp; value)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;//&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;These are almost identical, except that they use wregex, wstring and wistringstream instead of regex, string and istringstream.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;The overload mechanism&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;By now you may have wondered about the function overloading, if you are into template laws.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 4 overloads (removed template specifier &lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;for clarity):&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;bool&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; ParseArg(regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, T&amp;amp;);&lt;br /&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, TriStateVal&amp;lt;T&amp;gt;&amp;amp;);&lt;br /&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(wregex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, wstring &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, T&amp;amp;);&lt;br /&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(wregex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, wstring &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, TriStateVal&amp;lt;T&amp;gt;&amp;amp;);&lt;br style="mso-special-character:line-break;" /&gt;&lt;br style="mso-special-character:line-break;" /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It is simple enough to see how the compiler chooses based on the types of the pattern and the argument. That is via normal overloading rules.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But how does it know when to pick the generic T template function or the more specific TriStateVal&amp;lt;T&amp;gt; template? Both can be valid.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As it turns out, the compiler can follow the rules laid out in the C++ ISO standard section 14.5.5.2, which states that if multiple template functions are valid for the supplied template types, the most specific one will be selected.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The wording is of course more complex and formal than the previous paragraph, but that is what it boils down to. Section 14.5.5.2.5 contains a number of helpful examples, and one of them is equivalent with the ParseArg function.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;TriStateVal&amp;lt;T&amp;gt; is more specific than T, so the function with that parameter type will be used whenever possible.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Evaluation of the first attempt&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The first implementation works very well. You use the ParseArg function like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;wregex reFile(L&lt;span style="color:#a31515;"&gt;&amp;quot;^[-/]file[:=]\&amp;quot;{0,1}([^\\?\\*/&amp;lt;&amp;gt;\\\&amp;quot;]*)\&amp;quot;{0,1}$&amp;quot;&lt;/span&gt;);&lt;br /&gt;wregex reRows(L&lt;span style="color:#a31515;"&gt;&amp;quot;^[-/]rows[:=]([0-9]*)$&amp;quot;&lt;/span&gt;);&lt;br /&gt;wregex reCols(L&lt;span style="color:#a31515;"&gt;&amp;quot;^[-/]cols[:=]([0-9]*)$&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; _tmain(&lt;span style="color:blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; numRows = 0;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;TriStateVal&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numCols;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;wstring file;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt; i=0; i&amp;lt; argc; i++)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;wstring arg(argv);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(ParseArg(reRows, arg, numRows))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;continue&lt;/span&gt;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(ParseArg(reCols, arg, numCols))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;continue&lt;/span&gt;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(ParseArg(reFile, arg, file))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;continue&lt;/span&gt;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;wcout &amp;lt;&amp;lt; &lt;span style="color:#a31515;"&gt;&amp;quot;numRows : &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; numRows &amp;lt;&amp;lt; endl;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;wcout &amp;lt;&amp;lt; &lt;span style="color:#a31515;"&gt;&amp;quot;numCols : &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; numRows &amp;lt;&amp;lt; endl;;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;wcout &amp;lt;&amp;lt; &lt;span style="color:#a31515;"&gt;&amp;quot;file : &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; file &amp;lt;&amp;lt; endl;;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, no matter how many command parameters there are and how complex their formatting is, parsing them remains trivial if you can correctly specify the regular expressions.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The regular expressions in my example also take care of the fact that users can use either the &amp;ndash; or the / to precede identifiers, and that the value delimiter can be a = or : sign.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The great benefit of the TriStateVal is that you don&amp;rsquo;t have to keep track of Boolean variables, indicating the status of a variable. I.e. you don&amp;rsquo;t have to manually keep track of which variables were assigned.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If your application can do several things, based on a &amp;lsquo;command&amp;rsquo; parameter for example, then you can check the TriStateVal variables for that command to see if those have been assigned to. If will make your whole program easier to understand.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Problems with the first attempt&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;One&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;issue is that it sadly doesn&amp;rsquo;t work if T is of type &amp;lsquo;char&amp;rsquo; or &amp;lsquo;wchar_t&amp;rsquo;. The reason is that these types are the character types which make up &amp;lsquo;string&amp;rsquo; and &amp;lsquo;wstring&amp;rsquo;, and streaming from a string stream into a char is not supported.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Another possible issue is that in the case that T is of type bool, the text value has to be 1 or 0. Perhaps we would also like to be able to use &amp;lsquo;on&amp;rsquo; and &amp;lsquo;off&amp;rsquo; as valid value texts, or &amp;lsquo;high&amp;rsquo; and &amp;lsquo;low&amp;rsquo;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Both problems can be solved by providing more specific template functions, like (removed template specifier &lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;for clarity):&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &amp;lt;&amp;gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; &amp;amp;);&lt;br /&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&amp;gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(regex &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, string &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp;, &lt;span style="color:blue;"&gt;char&lt;/span&gt; &amp;amp;);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But if we want to implement those functions, we not only have to implement the string-regex function, but also the wstring-wregex function, and the functions that use TriStateVal parameters.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So instead of having to write 2 additional functions, we would have to implement 8 functions.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We could partially fix that by making the regex and string parameters templates instead of qualified types, but that does not fix the problem of the types that are used internally (smatch and istringstream).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, we could make those template arguments as well, but that would break automatic type inference, and force the programmer to specialize the template function explicitly, which would be ugly and confusing.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So instead we use a trick that is also used in the STL itself: we use a helper class that deduces those internal types for us.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Second attempt&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The key to the second attempt is to use a helper class that &amp;ndash;through specialization- will specify the dependent types.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The coat hanger for this mechanism is the empty class&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; strType&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;struct&lt;/span&gt; __pca_typehelper{};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;which has 2 specializations:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;struct&lt;/span&gt; __pca_typehelper&amp;lt;std::string&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::tr1::smatch MatchType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::istringstream SStreamType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::tr1::regex RegexType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;struct&lt;/span&gt; __pca_typehelper&amp;lt;std::wstring&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::tr1::wsmatch MatchType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::wistringstream SStreamType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; std::tr1::wregex RegexType;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Depending on which specialization is picked, MatchType, SStreamType and RegexType are typedef&amp;rsquo;ed to the correct STL and TR1 types.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And the nice thing is that is the user supplies something other than string or wstring, compilation will fail at this stage already, because those typedefs don&amp;rsquo;t exist.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Using that helper class, the ParseArg function can be written like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;template&lt;/span&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; Targ, &lt;span style="color:blue;"&gt;typename&lt;/span&gt; Tresult&amp;gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; ParseArg(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; __pca_typehelper&amp;lt;Targ&amp;gt;::RegexType &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; pattern,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Targ &lt;span style="color:blue;"&gt;const&lt;/span&gt;&amp;amp; arg,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Tresult&amp;amp; value)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; __pca_typehelper&amp;lt;Targ&amp;gt;::MatchType matches;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;( !std::tr1::regex_search(arg, matches, pattern))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; __pca_typehelper&amp;lt;Targ&amp;gt;::SStreamType&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;iss((Targ) matches[1]);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; ! (iss &amp;gt;&amp;gt; std::dec &amp;gt;&amp;gt; value).fail();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, there are now 2 template arguments: Targ and Tresult.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The meaning of Tresult is still the same as in the previous implementation.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Targ is new, and is the type of the argument that needs to be parsed. In our example it is either string or wstring. This type is then used to specialize __pca_typehelper so that the type of the regular expression can be deduced:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;typename&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; __pca_typehelper&amp;lt;Targ&amp;gt;::RegexType&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The same goes for the internal variables &amp;lsquo;matches&amp;rsquo; and &amp;lsquo;iss&amp;rsquo;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The implementation for the TriStateVal&amp;lt;Tresult&amp;gt; specialization is very similar to the one for Tresult so I am not going to repeat that here.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Evaluation of the second attempt&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;We got rid of the code duplication (which is good) and managed to have some fun in the process of doing so. At least I did. &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code still behaves as it did previously, so using the ParseArg function hasn&amp;rsquo;t changed at all.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We still have the issues about bool and char, but at least we can now solve this problem with a lesser number of specializations (4 instead of 8).&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;My implementation of ParseArg works good, and is easy to use. I&amp;rsquo;ve been using it for some time, but used boost for the regexes.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I would like to try and get the TriStateVal&amp;lt;T&amp;gt; and T scenarios to be handled by the same function. That would require providing a &amp;gt;&amp;gt; stream operator for TriStateVal&amp;lt;T&amp;gt; and I don&amp;rsquo;t know how much work that is.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I feel like giving this a try, but I am not going to wait with publishing this article. For one thing, it is already lengthy enough, but it also won&amp;rsquo;t matter from the user&amp;rsquo;s point of view. The usage of ParseArg will not change, so I feel it is perfectly acceptable to leave this optimization for another article.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code of this article is available for download as always.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And as always, if you have any comments or feedback, please leave a comment at the bottom of the page.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1644623" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.64.46.23/ParseArg.zip" length="7833" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>VC2008 feature pack released</title><link>http://msmvps.com/blogs/vandooren/archive/2008/04/08/vc2008-feature-pack-released.aspx</link><pubDate>Tue, 08 Apr 2008 20:50:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1578554</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1578554</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1578554</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/04/08/vc2008-feature-pack-released.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/vcblog/archive/2008/04/07/visual-c-2008-feature-pack-released.aspx"&gt;http://blogs.msdn.com/vcblog/archive/2008/04/07/visual-c-2008-feature-pack-released.aspx&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Finally we get TR1 with VC2008. Get it while it&amp;#39;s hot. This allows me to move a codebase to VC2008 and removing the dependency on boost.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1578554" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Differences between C++ and C#, part 3</title><link>http://msmvps.com/blogs/vandooren/archive/2008/02/27/differences-between-c-and-c-part-3.aspx</link><pubDate>Wed, 27 Feb 2008 11:52:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1525890</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1525890</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1525890</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/02/27/differences-between-c-and-c-part-3.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;One of the things that C# (and VB.NET) programmers have to live with is non-deterministic destruction of their objects.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The garbage collector was introduced in .NET to take care of memory leaks and remove the need for manual memory management. It does this by keeping track of references, and as soon as an object is no longer referenced, it ‘can’ be collected by the garbage collector.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The ‘can’ is important here, because cleanup happens only when the GC thinks is should happen. On systems with lots of memory, and few memory allocations and releases, it is possible that this takes minutes or hours, or even doesn’t happen at all.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This can be a real problem, because now you don’t have memory leaks anymore, but resource leaks.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Suppose your app opens a file for writing, and does not explicitly dispose of the stream reference.&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;FileStream&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; stream =&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;FileStream&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;Path&lt;/span&gt;.GetTempFileName(), &lt;span style="COLOR:#2b91af;"&gt;FileMode&lt;/span&gt;.Open);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;StreamWriter&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; writer = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;StreamWriter&lt;/span&gt;(stream);&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;writer.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Hello, world.&amp;quot;&lt;/span&gt;);&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;writer.Close();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The file is written and flushed to disk, but as long as the garbage collector does not collect the ‘stream’ object, it will hold an open file handle that will prevent you or anyone else from accessing that file. To overcome this you have to make sure that the file is released. On way of doing that would be like this:&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;FileStream&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; stream = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;FileStream&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;Path&lt;/span&gt;.GetTempFileName(), &lt;span style="COLOR:#2b91af;"&gt;FileMode&lt;/span&gt;.Open);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;try&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:#2b91af;"&gt;StreamWriter&lt;/span&gt; writer = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;StreamWriter&lt;/span&gt;(stream);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;writer.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Hello, world.&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;writer.Close();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;finally&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;stream.Dispose();&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;You could also use the ‘using’ keyword, but the same holds true. It is easy to make mistakes, and if you have several of such objects in the same scope, then your code will become a convoluted mess of nested try/finally or using constructs.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;In C++/CLI, this problem can be solved differently.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;In native C++, they way you create an object determines whether it will live on the stack or in the heap. The location implies the way the object will be cleaned up. If it is on the stack, it will be released automatically when it goes out of scope.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;C++/CLI does not have the ability to create managed objects on the stack, but it supports stack like semantics. I.e. even if you use the declaration that would put the object in the stack, it is still created in the managed heap. But the syntax and the semantics are stack based.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This means that in the following example, the stream object will automatically be released when it goes out of scope.&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;FileStream stream(Path::GetTempFileName(), FileMode::Open);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;StreamWriter writer(%stream);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;writer.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Hello, world.&amp;quot;&lt;/span&gt;);&lt;/span&gt; 
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;writer.Close();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;And regardless of how many such objects we need to create or use locally, they will all be cleaned up automatically without needing ugly nested structures, and without needing extra lines of code.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Of course, you still have to determine if this is something you want, because sometimes you need objects to live beyond the scope in which they were created. In that case you can use the gcnew operator to use heap semantics.&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;mso-layout-grid-align:none;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;FileStream^ stream = &lt;span style="COLOR:blue;"&gt;gcnew&lt;/span&gt; FileStream(Path::GetTempFileName(), FileMode::Open);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:&amp;#39;Times New Roman&amp;#39;;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;C++ gives you the ability to choose the best approach, which is nice if you want to write correct code without wanting to increase the number of lines of code, and structural complexity.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1525890" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2300_/default.aspx">C#</category></item></channel></rss>