<?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 : cplusplus</title><link>http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx</link><description>Tags: cplusplus</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>Practical ATL: recognizing marshalling problems</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/27/practical-atl-recognizing-marshalling-problems.aspx</link><pubDate>Tue, 27 Jan 2009 11:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666343</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=1666343</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1666343</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/27/practical-atl-recognizing-marshalling-problems.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;Before I publish my next article, I should explain something else about the black magic aspect of ATL / COM: Marshalling.&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 Stuff server we made in the previous article is an out-of-proc server. This means that the arguments being passed to / from a stuff instance have to be somehow moved back and forth between different process contexts (or different threading apartments).&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 the case of IStuff, we don&amp;rsquo;t really have to bother, because IStuff derives from IDispatch. And in that case, there is a marshaller (aptly named Universal Marshaller) that can be used to do all this for you.&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 IStuff wouldn&amp;rsquo;t derive from IDispatch, then we would need to provide our own proxy &amp;ndash; stub interface that knows how to marshal the interface. With ATL, this is not difficult. You&amp;rsquo;ll notice that the Stuff solution of my previous article had a &amp;lsquo;Stuff_ServerPS&amp;rsquo; project that I didn&amp;rsquo;t mention before.&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 solution will build the proxy stub dll that will perform the marshaling. It is disabled by default, so you have to enable it in the build configuration before it is built. Also remember to rebuild the proxy, every time the IDL files of your project change.&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 the remainder of this article I will show what can happen if there is a marshalling problem. &lt;b style="mso-bidi-font-weight:normal;"&gt;Don&amp;rsquo;t worry if it all seems ugly, gory, and incomprehensible. Normally you won&amp;rsquo;t have to deal with issues like this. But if you should ever do, you should at least recognize the signs that you have a marshaling problem&lt;/b&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;Confused? It&amp;rsquo;s the marshaller&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;If you find yourself in a situation where very weird things happen, suspect a marshalling problem.&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 get the error code E_NOINTERFACE when you know for sure that your object implements it properly, suspect a marshalling problem.&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 get a crash while using an interface pointer that was properly created without getting a HRESULT that indicated a problem,&amp;hellip; that&amp;rsquo;s right: you can bet it&amp;rsquo;s a marshaling problem.&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;Example&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 article I am currently writing discusses implementing a non standard class object, for the purpose of parameterized construction of the Stuff object. Never mind for the moment about what any of that means.&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 all practical purposes: it just means that I defined the following interface via copy / paste / edit:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;" 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:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&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;local&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;dual&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;void&lt;/span&gt; ** 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;There were 4 things wrong with this interface (showing just why you shouldn&amp;rsquo;t define IDL interfaces in a hurry). This has to be some sort of record.&lt;/span&gt;&lt;/p&gt;
&lt;ol 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;&amp;lsquo;local&amp;rsquo; shouldn&amp;rsquo;t be there.&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;&amp;lsquo;dual&amp;rsquo; shouldn&amp;rsquo;t be there.&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;&amp;lsquo;void&amp;rsquo; should be &amp;lsquo;IUnknown&amp;rsquo;&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;&amp;lsquo;ppStuff&amp;rsquo; should be attributed with riid_is(riid).&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So let&amp;rsquo;s have a look at the result of these different issues.&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;Issue 1: local&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;&amp;lsquo;local&amp;rsquo; simply shouldn&amp;rsquo;t be there. &amp;lsquo;local&amp;rsquo; is a MIDL attribute that &amp;ndash;when use in an interface header- causes MIDL not to generate stubs for that 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;The effect on our interface is that the IStuff specific methods are not forwarded to the remote server.&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 might wonder: why does it exist. The answer is: in case you want to write custom marshalling code, or in case the calls never have to be remoted. In that case you can have a local interface and a remote interface. And usage and marshalling could be optimized.&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;IUnknown is such an interface. But it has custom stub code to deal with things like remoting&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 result of using &amp;lsquo;local&amp;rsquo; on my IStuffCreator interface is that trying to call GetEnum on the returned IStuff interface pointer will result in a debug assertion: &lt;i style="mso-bidi-font-style:normal;"&gt;Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.&lt;/i&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;And if you have this problem with COM, it is usually indeed an indication that you have a calling convention mismatch. In this case, it is a side effect of the fact that we are trying to execute a method that isn&amp;rsquo;t remoted.&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;Issue 2: dual&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;This one shouldn&amp;rsquo;t be here either. Dual indicates that the interface implements IDispatch, and this could have an effect on marshalling.&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 this case, it worked just fine. Perhaps it is because of the fact that I use my object as a class object, or perhaps because my interface itself uses only arguments that are automation compatible, or perhaps because the stars are aligned in the proper configuration.&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 don&amp;rsquo;t know. And anything you don&amp;rsquo;t know for certain will hurt you when dealing with DCOM. It has to be correct.&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;Issue 3: void&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;This one is interesting.&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 I want to pass an interface pointer, it has to be passed as an IUnknown**, instead of a void**. This is because Universal Marshaller has no idea on how to marshal something which has only contextual meaning, nor does the IDL compiler know what you mean with 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;With this I mean that my server knows it will be an interface pointer, and my client will know it is an interface pointer, but the stuff in the middle doesn&amp;rsquo;t. It sees just a memory address.&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 used void** because that is what QueryInterface itself uses. And what&amp;rsquo;s good enough for QI should be good enough for me. Except QI has custom code for marshalling its arguments across, which I don&amp;rsquo;t. So QI can use void** because both the proxy and the stub know what is going 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;So what happens when you use 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;I request the class object like this:&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;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; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(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;&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;CLSCTX_ALL,&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;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&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;void&lt;/span&gt;**)&amp;amp;stuffClass);&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;And the resulting hr is 0x80020008: Bad variable type. There is absolutely nothing wrong with this line of code. But because there is something in the interface itself that confuses the marshaller, it tells me to sod off when I want that specific interface.&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;Credit where it is due: I figured this one out thanks to someone whose name I can&amp;rsquo;t figure out &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;. But his blog post is &lt;a href="http://www.ajitatif.com/CategoryView,category,ATL.aspx" title="http://www.ajitatif.com/CategoryView,category,ATL.aspx"&gt;here&lt;/a&gt;.&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;Issue 4: iid_is(riid)&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;This one is also a good one.&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 iid_is informs the marshaller that riid points to the identifier which identifies the interface that is being marshaled.&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 way, the marshaller knows how to marshal the interface that was specified with riid. Without that part, it would only marshal the IUnknown part of the interface, and not the IStuff specific part.&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 a result, you can use the IUnknown part of the interface without a problem, but if you use the IStuff specific part, you will get an access violation, stack corruption or other interesting phenomenon.&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;A couple of things can be concluded at this point.&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 of all: Marshaling problems are hard to debug, because the problems occur outside of your source 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;If you use any interfaces that don&amp;rsquo;t derive from IDispatch, then you have to enable the &amp;lsquo;xxxPS&amp;rsquo; project in your solution so that the ProxyStub dll will be built and registered. And of course, this dll has to be part of your install procedure. Without this stub, you could get access violations, or you get an E_NOINTERFACE error if the marshaler doesn&amp;#39;t know one of those interface 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;As I have shown, you need to be careful and pay attention when you manually define COM interfaces. If you don&amp;rsquo;t, then you can have all sorts of hard to diagnose 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;And if you ever find yourself in a situation where nothing makes sense, then suspect marshalling issues and have a long hard look at your IDL files.&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=1666343" width="1" height="1"&gt;</description><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>File a bug report and make Visual Studio a better product</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/22/file-a-bug-report-and-make-visual-studio-a-better-product.aspx</link><pubDate>Thu, 22 Jan 2009 06:50:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1664610</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=1664610</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1664610</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/22/file-a-bug-report-and-make-visual-studio-a-better-product.aspx#comments</comments><description>&lt;p&gt;If you find a bug in Visual Studio, report it on &lt;a href="http://connect.microsoft.com"&gt;http://connect.microsoft.com&lt;/a&gt;&amp;nbsp;If the bug affects the version of VS that is in development at that time, there is a significant chance it will get fixed before the next release. Just this week I got confirmation that all 3 bugs that I filed in the last months have been resolved.&lt;/p&gt;
&lt;p&gt;The first one is a nasty one. &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506"&gt;If you add an ATL project to an existing, non-empty solution, the ATL wizards will either hang the IDE or fail to work when adding an ATL object&lt;/a&gt;. I found a workaround for it, but it involved hand editing the solution file.&lt;/p&gt;
&lt;p&gt;The second one is a &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;small bug in the TR1&lt;/a&gt; regex parser. No workaround, other than to restructure the regex.&lt;/p&gt;
&lt;p&gt;And the last one was an &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;error in the MSDN documentation about open modes with the fopen family&lt;/a&gt;, which counts as a bug because it triggered runtime errors.&lt;/p&gt;
&lt;p&gt;All 3 have been fixed. I especially appreciate the first one. I am working on ATL projects, and I develop my COM server in&amp;nbsp;the same solution as a couple of related non-ATL projects. So every time I work with ATL projects, I can have a warm and fuzzy feeling that because of me, VS is now a better product. :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1664610" 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/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Practical ATL: Implementing an enumerator object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/21/practical-atl-implementing-an-enumerator-object.aspx</link><pubDate>Wed, 21 Jan 2009 19:55:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1664320</guid><dc:creator>vanDooren</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1664320</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1664320</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/21/practical-atl-implementing-an-enumerator-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;This is my first article about practical ATL examples, which I already mentioned here.&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 this example I will create an ATL Server which implements 1 custom interface: IStuff. Hardly an inspiring name, but I couldn&amp;rsquo;t think of anything better before I had my first coffee.&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 interface will have 1 method which will return an enumerator to the caller. Specifically, this enumerator will implement IEnumString.&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;Enumerators are part of the interface of many real-life COM servers, but creating your own is an arduous task. ATL makes this much easier, but an example makes things so much easier still.&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;Since client code will have to deal with this enumerator (and to have a demo app) I will also create a client application that creates an instance of the server, consumes the IStuff interface and then enumerate the items contained in the returned enumerator.&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;Before we get started&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;If you don&amp;rsquo;t own a copy of &amp;lsquo;ATL Internals, Second Edition&amp;rsquo; yet, I strongly advise you to buy it. It is worth the money, and apart from leading you through all the interesting and gory stuff, it also starts by explaining the actual process of creating an ATL server through the IDE, as well as implementing methods, properties and events.&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 am only going to cover that aspect very lightly. It should be detailed enough for anyone who has done C++ development using VS:&lt;/span&gt;&lt;/p&gt;
&lt;ol 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;Create a new ATL Server project with project name &amp;lsquo;Stuff_Server&amp;rsquo; and a solution name &amp;lsquo;Stuff&amp;rsquo;.&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;Choose the EXE project type and click &amp;lsquo;finish&amp;rsquo;&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;Add a new class to the project, and specify ATL Simple Object. Use &amp;lsquo;Stuff&amp;rsquo; as the name of the object.&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;Switch to classview, and add a new method to the IStuff interface with the prototype &amp;lsquo;HRESULT GetEnum(IUnknown ** ppEnum).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;ppEnum should be marked as an &amp;lsquo;out&amp;rsquo; parameter.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Build the project, and you should be ready for the actual work. The ATL wizards will have implemented all the IDL and DCOM stuff for you, and you only have to implement the functionality.&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;Finally, I always end by changing the project configuration to use static CRT and ATL runtimes instead of dynamic runtimes. This makes it infinitely more easy to distribute the resulting executables without having to bother with registration and installation of the runtime dlls and their manifests.&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;Creating the server&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;Now that the ATL wizards have generated the function skeleton for us, it is time to do something with it:&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;STDMETHODIMP CStuff::GetEnum(IUnknown** ppEnum)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&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 enumerator&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;Before we can do anything else, we have to think about the actual enumerator for a bit. In our case we implement IEnumString. This is an interface for enumerating string (who&amp;rsquo;d have thought, eh?).&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;Enum interfaces all look alike, and ATL helpfully has a stock implementation for generic enumerators that allows you to specify the Interface, GUID, datatype and data type copy traits as template parameters. In order to facilitate coding, we make a typedef for this class:&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;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CComEnum&amp;lt;&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;IEnumString,&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;&amp;amp;IID_IEnumString,&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;LPOLESTR,&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;_Copy&amp;lt;LPOLESTR&amp;gt; &amp;gt; CComEnumStringAbstract;&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;This will specialize the enumerator for our purposes. The use of the first 3 parameters is obvious. Don&amp;rsquo;t worry about the _Copy parameter. I will cover that later.&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 enumerator itself is a normal COM object, so it needs lifetime management, interface managements, and all other things you really don&amp;rsquo;t want to care about for something so simple. At this point, &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CComEnumStringAbstract&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; will still be an abstract class because it can&amp;rsquo;t decide how to do these things for you.&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 order to make our enumerator a full fledged COM object, we have to shove it into a bare COM object. This is very easy:&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; CComObject&amp;lt;CComEnumStringAbstract&amp;gt; CComEnumString;&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 that is all there is to creating an enumerator! Anyone who has ever implemented one manually will agree that this is infinitely more convenient&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 GetEnum&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 for GetEnum is also fairly easy (comments removed for clarity)&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;STDMETHODIMP CStuff::GetEnum(IUnknown** ppEnum)&lt;br /&gt;{&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComEnumString * thEnumObj&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;= NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = CComEnumString::CreateInstance(&amp;amp;thEnumObj);&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;(FAILED(hr))&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; hr;&lt;br /&gt;&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;CComEnumString&amp;gt; thEnum(thEnumObj);&lt;br /&gt;&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LPOLESTR strings[] = {L&lt;span style="color:#a31515;"&gt;&amp;quot;One&amp;quot;&lt;/span&gt;, L&lt;span style="color:#a31515;"&gt;&amp;quot;Two&amp;quot;&lt;/span&gt;, L&lt;span style="color:#a31515;"&gt;&amp;quot;Three&amp;quot;&lt;/span&gt;, NULL};&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;hr = thEnum-&amp;gt;Init(&amp;amp;strings[0], &amp;amp;strings[3], NULL, AtlFlagCopy);&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;(FAILED(hr))&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; hr;&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;hr = thEnum-&amp;gt;QueryInterface( &lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppEnum);&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; hr;&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;First we create a new &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CComEnumString&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; object. It is worth noting that the object returned by &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CreateInstance&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; has a refcount of 0. Before we do anything with it we should AddRef it, but instead of doing that manually, I do it via assignment to the CComPtr. smart pointer. That way the object also gets released automatically at the end.&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;Then we have to make sure the enumerator has some data to enumerate. We do this by populating an array, and then telling the enumerator to copy the data out of it into its own internal buffer. This is done via the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagCopy&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag.&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 might seem weird if you come from a C background, but the &amp;lsquo;End&amp;rsquo; pointer has to point to the first position beyond the last element. This is normal with collections in C++. That is also why I populate the array with a NULL pointer at the end; So that there is something in the array after the last &amp;lsquo;real&amp;rsquo; element. This way there is no buffer overflow.&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 &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagCopy&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; has the overhead of having to copy the data, but otoh the enumerator does not have to care about the lifetime of the array. We could also use new[] to create a new array and then use the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagTakeOwnership&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag to indicate that it is up to the enumerator to call delete[] and clean up. But in this example we can&amp;rsquo;t do that (read below).&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 the enumerator is initialized, we return an IUnknown interface pointer to the caller. Since this will have increased the enumerator ref count, the enumerator object will keep on living when the CComPtr goes out of scope and releases its own reference to the enumerator.&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;There. That is all there is to it on the server side. No vast amounts of copy pasted boilerplate code, but just a couple of lines of powerful ATL incantations &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;_Copy&amp;lt;LPOLESTR&amp;gt; revisited&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 an enumerator has to copy data to a client, or if it has to copy data into its internal buffers in the &amp;lsquo;Init&amp;rsquo; function, it has to know how to do this.&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 all good and well to do a simple memcpy of an ULONG or a double, but for strings (LPOLESTR) and interface pointers (IUnknown) this won&amp;rsquo;t work. There&amp;rsquo;s ref counting and memory ownership to deal 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;Of course, the template class, not knowing about this, can&amp;rsquo;t anticipate what you want, so instead it needs a policy class to delegate to. That is where the _Copy&amp;lt;&amp;gt; template class comes in. It has 3 methods: Init, Destroy, and Copy. Those methods perform the actual operations needed to copy an instance of T to another instance of T, to initialize a new one, and to destroy one.&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 several stock specializations for _Copy&amp;lt;&amp;gt;, one of which works for LPOLESTR. So rather than copying the LPOLESTR pointer itself, it calls CoTaskMemAlloc to create a buffer for the copy of the string, and then copies over the data.&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 look at my example more closely, you will also see why I cannot simply new up an array of string literals and pass those to the Init function with the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagTakeOwnership&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag.&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;LPOLESTR is superficially identical to wchar_t*. So using a string literal instead of an LPOLESTR (which is what I do in my example) will work without a hitch. But if I&amp;rsquo;d new up an array and tell the enumerator to manage it, that is when it would all go 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;Because the enumerator would not only call delete[] on the array, but it would also call _Copy::Destroy for each of the items. And trying to free up a string literal with CoTaskMemFree will result in a hard to diagnose 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;Installing the server&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;On a development station this is done automatically by Visual Studio. But if you need to do this on another PC, you just execute the server from the command line with the /RegServer argument.&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;Creating the Client&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;Creating the client application is fairly simple, but I wanted to show how to do it anyway, because then I could demonstrate that the COM server works as intended.&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 create a simple win32 console application so that I only had to care about the actual functionality.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Importing the server type library&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;In the olden days or yore, working with COM servers in a C++ project was a bit tedious. You had to include the IDL files in your project and compile them, then include the resulting header files, add the .c files to your project for the GUID definitions&amp;hellip; Not rocket science by any means, but still&amp;hellip; a bit messy and ugly.&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;Now, I have &lt;i style="mso-bidi-font-style:normal;"&gt;very&lt;/i&gt; few kind words for Visual Basic, but to give credit where it is due: Visual Basic is (in large part) responsible for the existence of tlb files.&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;Visual Basic programmers wanted to use COM too, and the people who made Visual Basic wanted to prevent the application programmers to have anything to do with IDL. They wanted Visual Basic to take care of all that mess behind the scenes.&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 thus the type library (tlb) was born.&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 type library contains the same stuff as the IDL files, but in a machine readable, programming language independent format.&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 a COM server, you need to do nothing more than add the following line to the StdAfx.h header file of the client program:&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;#import&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;Stuff_Server.tlb&amp;quot;&lt;/span&gt; no_namespace&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 also need to make sure that the compiler knows where to find Stuff_Server.tlb. This is easily done by adding the following line to the &amp;lsquo;Additional include directories&amp;rsquo; setting:&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;..\Stuff_Server\$(ConfigurationName)&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 then compile StdAfx.cpp, the compiler will pull in the type library and generate the appropriate headers which are then automatically included.&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 no_namespace attribute tells the compiler that it shouldn&amp;rsquo;t put the declarations in a specific namespace.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Using the COM server&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 client application code itself is fairly 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;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;/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;HRESULT hr = CoInitialize(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; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(SUCCEEDED(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&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; 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;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = CoCreateInstance(&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), NULL, CLSCTX_ALL,&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;(IStuff), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;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;&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;CComPtr&amp;lt;IUnknown&amp;gt; thEnumUnk;&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 = stuff-&amp;gt;GetEnum((IUnknown **)&amp;amp;thEnumUnk);&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;CComPtr&amp;lt;IEnumString&amp;gt; thEnum;&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;thEnumUnk-&amp;gt;QueryInterface(&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IEnumString), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**) &amp;amp;thEnum);&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:blue;"&gt;do&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&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;LPOLESTR 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; &lt;/span&gt;hr = thEnum-&amp;gt;Next(1, &amp;amp;str, 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; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(hr == S_OK )&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; &lt;/span&gt;wprintf(L&lt;span style="color:#a31515;"&gt;&amp;quot;%s\n&amp;quot;&lt;/span&gt;, 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; &lt;/span&gt;CoTaskMemFree(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; &lt;/span&gt;}&lt;span style="color:blue;"&gt;while&lt;/span&gt; (hr == S_OK );&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;CoUninitialize();&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; 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&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 I initialize the COM runtime and then create a new instance of the Stuff object. I request IStuff as the initial interface. I also use the &lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;__uuidof&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; keyword to get the GUID for an interface / object instead of using the CLSID_ and IID_ parameters. In my opinion, it is more convenient.&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 COM smart pointer takes care of the reference counting for me. This is most convenient, because then I am certain that it will get released properly without me having to worry about 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;Btw, this is also the reason that all the code is placed into a separate scope block after the call to CoInitialize. The smart pointers clean up their interface pointers when they go out of scope. If CoUninitialize would have been called before that, it would lead to weird problems / crashes.&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;Via the IStuff interface I request an enumerator object. This gets returned as an IUnknow interface, so I have to get the IEnumString interface via the IUnknown::QueryInterface method. So that&amp;rsquo;s 3 interfaces already, and I still don&amp;rsquo;t have to care about reference counting &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 that I use the &amp;lsquo;Next&amp;rsquo; method of the IEnumString interface to retrieve the items contained in the enumerator. This the only place where I have to perform a manual cleanup action.&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 IEnumString interface does not work with BSTRs, it works with LPOLESTRs. While these are code compatible because they are the same type of data, their semantics are not. The _Copy&amp;lt;LPOLESTR&amp;gt; mentioned earlier allocates data for the string using CoTaskMemAlloc. It has to be freed by CoTaskMemFree.&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;CComBSTR would use SysAllocString and SysFreeString. And while the code would compile and execute perfectly, there would be an crash as soon as the CComBSTR would try to free the string it got from the call to &amp;lsquo;Next&amp;rsquo;.&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;As you can see, implementing COM servers and clients can be really easy with the proper use of ATL. And you&amp;rsquo;ve also seen that implementing an enumerator object is made really easy.&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 demo code is up for download with this article under the MIT license. Have fun.&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 will probably write some more ATL / COM stuff soon. Stay tuned for more DCOM archaeology from the mists of time ;-)&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1664320" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.66.43.20/Stuff_5F00_V1.zip" length="25052" type="application/x-zip-compressed" /><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>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>Creating a thread safe producer consumer queue in C++ without using locks</title><link>http://msmvps.com/blogs/vandooren/archive/2007/01/05/creating-a-thread-safe-producer-consumer-queue-in-c-without-using-locks.aspx</link><pubDate>Fri, 05 Jan 2007 09:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:470800</guid><dc:creator>vanDooren</dc:creator><slash:comments>30</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=470800</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=470800</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2007/01/05/creating-a-thread-safe-producer-consumer-queue-in-c-without-using-locks.aspx#comments</comments><description>&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Yesterday, someone in the newsgroups asked a question about synchronization problems he was having. I explained that &amp;ndash;if properly programmed&amp;ndash; a consumer producer queue does not need synchronization even on a multiprocessor machine.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A Microsoft employee then asked me to explain exactly how this was done. Ie. To put my money where my mouth is.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;The idea&lt;/em&gt;&lt;/h2&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A queue is a chunk of memory that can be divided into equal sized pieces. To simplify this you can think of a queue simply as a traditional 1 dimensional C style array.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;You should also note that there is 1 reader, and 1 writer. Each will work in his own thread. This means that reads can happen&amp;nbsp;concurrent with writes, but there will be no multiple concurrent reads or multiple concurent writes. It is possible to provide that level of concurrency without locks (I did, once) but that is significantly more complex, and not the purpose of this 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:Times New Roman;"&gt;To manage the producer and consumer part, we need to have 2 additional variables: a read index and a write index.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The read index is the index of the element right after the element that was last read by the consumer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The write index is the index of the element right after the element that was last written by the producer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A writer can always add elements in the queue as long as it can move the write pointer without overtaking the read pointer. An overtake would mean that the queue would overflow.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 3 possible cases:&lt;/span&gt;&lt;/p&gt;
&lt;ol style="MARGIN-TOP:0cm;"&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l1 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The read and write pointers are equal. This is only possible if the queue is in the initialized state. Any read will result in a fail, any write will succeed.&lt;/span&gt;&lt;/li&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l1 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The read pointer is pointing to the first element after the write pointer. This means that the queue is full. If one more element would be added, the read and write pointers would be the same, and the reader would assume that the queue was empty. Any read will succeed, and write will fail.&lt;/span&gt;&lt;/li&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l1 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The read and write pointers are not equal, and the previous case was not true. Any read will succeed. Any write will succeed.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;The implementation&lt;/em&gt;&lt;/h2&gt;
&lt;h3 style="MARGIN:12pt 0cm 3pt;"&gt;Adding elements&lt;/h3&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" 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 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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; PushElement(T &amp;amp;Element)&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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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-tab-count:2;"&gt;&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:#0000ff;"&gt;int&lt;/span&gt; nextElement = (m_Write + 1) % Size;&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-tab-count:2;"&gt;&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:#0000ff;"&gt;if&lt;/span&gt;(nextElement != m_Read) &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-tab-count:2;"&gt;&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&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-tab-count:3;"&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;m_Data[m_Write] = Element;&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-tab-count:3;"&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;m_Write = nextElement;&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-tab-count:3;"&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;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&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-tab-count:2;"&gt;&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&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-tab-count:2;"&gt;&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:#0000ff;"&gt;else&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-tab-count:3;"&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;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" 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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&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 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As long as the first element after the write pointer is not the read pointer, it is not occupied. The element can be added and the write pointer can be updated.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Otherwise the queue is full and the write operation will fail.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="MARGIN:12pt 0cm 3pt;"&gt;Removing elements&lt;/h3&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" 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 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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; PopElement(T &amp;amp;Element)&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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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-tab-count:2;"&gt;&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:#0000ff;"&gt;if&lt;/span&gt;(m_Read == m_Write)&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-tab-count:3;"&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;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;false&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-tab-count:2;"&gt;&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:#0000ff;"&gt;int&lt;/span&gt; nextElement = (m_Read + 1) % Size;&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-tab-count:2;"&gt;&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;Element = m_Data[m_Read];&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-tab-count:2;"&gt;&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;m_Read = nextElement;&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-tab-count:2;"&gt;&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:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" 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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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:Times New Roman;"&gt;If the read pointer is equal to the write pointer, there is nothing to read. In any other case we can read the first element and update the read pointer.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;Why this is safe&lt;/em&gt;&lt;/h2&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The advantage of this scheme is that no locking is needed. Each of the pointers (indices really) is updated only by one thread.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This means there is no write concurrency as far as the pointers are concerned.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Furthermore &amp;ndash; and this is important &amp;ndash; the read and write pointers are updated only after the element concerned is read or written.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This means that if the read or write pointer changes, the elements are guaranteed to reflect that situation. The gap between the element change and the pointer change is invisible to the other threads.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So logically, this code is perfectly safe. However, one final issue must be highlighted, and that is the declaration of the pointers and the data array.&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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;volatile&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; m_Read;&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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;volatile&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; m_Write;&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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Size = 10;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" 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-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;volatile&lt;/span&gt; T m_Data[Size];&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If we take no precautions, the optimizer can reorder the actual memory operations on the read and write pointer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Or it could assume that variables do not change between calls and use cached values instead of what is actually in memory. This could be especially problematic on multi CPU machines where each CPU has its own cache.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;See the documentation for &amp;lsquo;volatile&amp;rsquo; in MSDN for a more detailed explanation.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;How this could be unsafe&lt;/em&gt;&lt;/h2&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There is one thing that is critical in this code, and that is that memory updates are not re-ordered. You can easily understand that if the write pointer gets updated before the actual data element is updated, there is a gap that creates a race condition.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Therefore it is critical that the platform this code runs on (CPU, chipset, memory controller) does not re-order the memory write operations. Otherwise you&amp;rsquo;d have this code that is logically thread-safe, but thread-unsafe due to CPU peculiarities. You&amp;rsquo;d have all sorts of impossible to debug problems.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;Extending functionality&lt;/em&gt;&lt;/h2&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The design as it is works reasonably well, but here are a couple of tips to make this into powerful code:&lt;/span&gt;&lt;/p&gt;
&lt;ul style="MARGIN-TOP:0cm;"&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l0 level1 lfo2;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Foresee an array of read pointers instead of using only one. That way you could have a broadcast queue in which each consumer has the opportunity to receive elements. You have to check each of the read pointers before writing to make sure that there is room enough in the queue.&lt;/span&gt;&lt;/li&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l0 level1 lfo2;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Allow the constructor to take a variable sized piece of memory that was previously constructed. Make the read and write pointers the first items in that memory. This allows you to put a queue on shared memory and communicate with other processes.&lt;/span&gt;&lt;/li&gt;
&lt;li style="MARGIN:0cm 0cm 6pt;mso-list:l0 level1 lfo2;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;hellip;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style="MARGIN:12pt 0cm 3pt;"&gt;&lt;em&gt;Conclusion&lt;/em&gt;&lt;/h2&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Making a multi thread safe consumer producer queue without synchronization is perfectly possible. If you want to play with the code, it is attached to this article and licensed under the MIT license.&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I whipped this code together in a very short time for the purpose of this demo. It should be bug free, but if you think there is something specifically wrong, let me know and I&amp;rsquo;ll see if there is a problem with it. &lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=470800" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.47.08.00/QueueDemo.zip" length="6907" 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>Fun with templates: implementing policy based error handling</title><link>http://msmvps.com/blogs/vandooren/archive/2006/10/02/Fun-with-templates_3A00_-implementing-policy-based-error-handling.aspx</link><pubDate>Mon, 02 Oct 2006 08:01:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:149559</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=149559</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=149559</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/10/02/Fun-with-templates_3A00_-implementing-policy-based-error-handling.aspx#comments</comments><description>&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This article is a follow up of my third article on interoperability for LabVIEW arrays in C++. That article provided a method for allowing programmers to index into multi dimensional arrays.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;As far as functionality went, the solution was OK, but the error handling left a lot to be desired. I also wanted the error handling strategy to be policy based. I.e. you should be able to choose at compile time whether the classes use return value error handling or exceptions, or maybe something else entirely, like structured exceptions.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;After some experimenting, I now have a decent solution that is elegant and maintainable.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;The general idea&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;After writing my previous article in this series, I was kicking around with a few ideas, but I got a great suggestion from my fellow MVP Eugene Gershnik.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Basically, it boils down to the following idea:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;struct&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EBThrowing&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; RetVal;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt; RetVal ReturnError(&lt;span style="color:blue;"&gt;int&lt;/span&gt; ErrorCode)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(0 != ErrorCode)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;throw&lt;/span&gt; Lvtl_Exception(ErrorCode);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;struct&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EBRetVal&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; RetVal;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt; RetVal ReturnError(&lt;span style="color:blue;"&gt;int&lt;/span&gt; ErrorCode)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; ErrorCode;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; EB&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CClass()&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; EB::RetVal foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; errorCode = 0;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; EB::ReturnError(errorCode);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This example defines 2 error handling policies. One policy specifies that error handling constitutes returning error codes. The other policy specifies that errors will be reported as exceptions.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Each of those policies has a typedef to define the &amp;lsquo;RetVal&amp;rsquo; type, as well as a function called &amp;lsquo;ReturnError&amp;rsquo;.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Each class that wants to implement policy based error handling has to be a template class that takes a policy class as input.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Return value types&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This is where the magic happens: all methods that could trigger an error have to have a return value type that is defined by the policy class. Since these types are resolved at compile time, the function&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;typename&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EB::RetVal foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;is equivalent to&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;if the error handling policy class is EBRetval. If the policy class is EBThrowing, the function is equivalent to&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;As a result, it is hard to accidentally misuse an instance of CClass, as far as error handling goes.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Suppose you try to use an instance of CClass that throws exceptions, in a situation where you expect return values will generate a compiler error because&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; ret = foo();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;cannot compile if foo is of type &lt;/font&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;void&lt;/span&gt;&lt;font face="Times New Roman" size="3"&gt;.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Because the type identity of CClass is determined in part by the error policy, it is impossible to pass an instance of &lt;/font&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;CClass&amp;lt;EBRetVal&amp;gt;&lt;/span&gt;&lt;font face="Times New Roman" size="3"&gt; where an instance of &lt;/font&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;CClass&amp;lt;EBThrowing&amp;gt;&lt;/span&gt;&lt;font face="Times New Roman" size="3"&gt; is expected or vice versa.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Raising errors&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Part of the policy contract is that the consuming classes never raise an error directly. I.e. they never return an actual value or throw an exception directly.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Instead, all errors will be raised by calling RaiseError.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;return&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EB::ReturnError(errorCode);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The ReturnError function has a return value of type &lt;/font&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;EB::RetVal&lt;/span&gt;&lt;font face="Times New Roman" size="3"&gt;. It depends on the policy. This is necessary because the methods of the consuming class also have this return type, and they have to match.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If the error policy prescribes error handling via return values, ReturnError simply does this:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;return&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; ErrorCode;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If the policy prescribes error handling via C++ exceptions, ReturnError simply does this:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;if&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;(0 != ErrorCode)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;throw&lt;/span&gt; Lvtl_Exception(ErrorCode);&lt;/span&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Not raising false errors&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Consider the following snippet:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;typename&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EB::RetVal foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; errorCode = 0;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; EB::ReturnError(errorCode);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The error code will be determined by what happens in foo. However, if there was no error, no error should be raised either. With standard exception handling, this would not be a problem, because foo would simply not raise an error if there was no error.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;But if return value error handling is used, foo always has to return a value, even if there was no error. In that case the general behavior is to return 0.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;CClass should never return a value directly, since this would break the policy contract. Instead it must always use ReturnError. This means that ReturnError will be called with 0 as the error code if there was no error. ReturnError should then check if the error code really indicates an error before doing anything.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Providing a default policy&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Template classes allow template parameters to be specified with default values. This makes it possible to use the template class without having to specify the default parameters. This makes the code more readable, and the program easier to write.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;However, in this case the code is meant to be used as a toolkit by other developers. If we provide a default policy, it will be wrong for half of the users.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; EB=EBThrowing&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CClass();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If I want to use the EBRetVal policy, I would still have to provide a value for the EB parameter.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;To solve this, I have changed CClass.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#ifndef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; LVTL_OVERRIDE_EB_DEFAULT&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EBThrowing&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;EBDefault;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#endif&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; EB=EBDefault&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CClass();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This construct allows me to specify a default &amp;lsquo;default&amp;rsquo; policy, while still allowing the user to override it with another default by supplying a custom typedef.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Usually, only 1 policy is used throughout the whole dll or application, so allowing the user to provide a default policy should in practice mean that they never have to supply one explicitly.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Limitation 1&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If you design classes that implement a policy based error handling strategy, you should take care that cleanup actions are policy agnostic.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;I.e. you must make sure that cleanup is done before you raise the error. For example, if you would like to enable the user to provide his own policy class that uses structured exceptions, you have to be aware that you cannot guarantee that objects will be properly destructed when an error is raised&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Limitation 2&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;You should also be aware that it is difficult to layer policy based classes on top of each other while retaining the policy scheme. This is demonstrated by the this implementation of foo, where bar is an instance of a CBar class that implements policy based error handling.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;typename&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; EB::RetVal foo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; errorCode = 0;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;bar-&amp;gt;SomeMethod();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; EB::ReturnError(errorCode);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The problem is obvious. How would you know that you need to cleanup and bail out if bar raised an error?&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;You cannot check its return value, nor catch an exception, because you don&amp;rsquo;t know which of those you will get. Remember, using policies means that you don&amp;rsquo;t know what bar will do in advance.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If you want to use CBar, you have to fix its policy in order to be able to use it reliably.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=149559" 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/cplusplus/default.aspx">cplusplus</category></item><item><title>Differences between C# and C++/CLI, part 2</title><link>http://msmvps.com/blogs/vandooren/archive/2006/08/31/Differences-between-C_2300_-and-C_2B002B002F00_CLI_2C00_-part-2.aspx</link><pubDate>Thu, 31 Aug 2006 20:58:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145317</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=145317</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145317</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/08/31/Differences-between-C_2300_-and-C_2B002B002F00_CLI_2C00_-part-2.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;One question that comes up from time to time in the C++ newsgroups is that functions or constants that exist in a C++/CLI class library are not accessible in a C# or VB.NET project.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;The reason for this is nearly always that that constants or functions are defined outside of a class scope.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;Consider the following - perfectly valid - C++/CLI:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;namespace&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; Bla&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;const&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; CONST = 42;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; func(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; CONST;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;You can use CONST and func in other C++/CLI code.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;What you can&amp;rsquo;t do is to use those symbols in other .NET languages. The reason is that those languages do not have a concept of things existing outside of a class or struct scope.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;In other words, even though the CLR supports it, languages other than C++/CLI do not support free standing functions, variables and constants.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;color:#003300;font-family:Verdana;"&gt;A simple workaround is to put them in a dummy class. For example, you could put all constants in a class called &amp;lsquo;Consts&amp;rsquo;, and functions in a class called &amp;lsquo;Functions&amp;rsquo;.&lt;/span&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145317" 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><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Differences between C# and C++/CLI, part 1</title><link>http://msmvps.com/blogs/vandooren/archive/2006/08/31/Differences-between-C_2300_-and-C_2B002B002F00_CLI_2C00_-part-1.aspx</link><pubDate>Thu, 31 Aug 2006 20:56:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145312</guid><dc:creator>vanDooren</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=145312</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145312</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/08/31/Differences-between-C_2300_-and-C_2B002B002F00_CLI_2C00_-part-1.aspx#comments</comments><description>&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Learning C# if you already know C++ is relatively easy. The syntax is similar, and the semantics are definitely a lot easier to understand.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Since C# looks like C++, most of the concepts are easy to learn, but here and there are a few details that might cause problems later on.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;On of these things is the difference between the meaning of classes and structures in C# and C++.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;C++&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;With C++, a distinction needs to be made between native C++ and C++/CLI&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Native C++&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Classes and structures are virtually identical in native C++. Instances can be located on the stack or on the heap. It all depends on how they are instantiated.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The only difference between the two is that in a class, the default access of a class member is private, while the default access of a structure member is public.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;That&amp;rsquo;s all there is to it.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;C++/CLI&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;With the rise of C++/CLI, the compiler needs to know&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt 36pt;text-indent:-18pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman"&gt;&lt;span&gt;&lt;font size="3"&gt;a)&lt;/font&gt;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;whether a type is managed or unmanaged, and&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt 36pt;text-indent:-18pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman"&gt;&lt;span&gt;&lt;font size="3"&gt;b)&lt;/font&gt;&lt;span style="font:7pt &amp;#39;Times New Roman&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;whether the type (if managed) is a reference or value type.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;To solve this, the new keywords &amp;lsquo;ref&amp;rsquo; and &amp;lsquo;value&amp;rsquo; are used. The term &amp;lsquo;ref &lt;em&gt;type&lt;/em&gt;&amp;rsquo; indicated a reference type. The type is managed, and is located on the managed heap. The term &amp;lsquo;value &lt;em&gt;type&lt;/em&gt;&amp;rsquo; indicates a managed value type. It is also managed, but located on the stack&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Type can be either a class or a structure. As a result, it is possible for classes to be value types, and structures to be reference types in C++.&lt;/font&gt;&lt;/p&gt;&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;Semantics&lt;/em&gt;&lt;/h2&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;In C++, the way in which you instantiate &amp;ndash; and not the declaration &amp;ndash; of a type determines whether it lives on the heap or on the stack.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;2 important consequences of type location in C++ are that stack based instances are fixed in memory during their lifetime, and that stack based instances are guaranteed to be cleaned up when the go out of scope.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;In reality, the C++ compiler is cheating you. It does some things behind your back to fool you into thinking that things live on the stack, while in reality they live on the managed heap.&lt;/font&gt;&lt;/p&gt;&lt;ul style="margin-top:0cm;"&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Native types are either allocated on the stack or the native heap, based on whether you use stack semantics or operator new.&lt;/font&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Value types can be created on the stack, on the native heap and on the managed heap, based on whether you instantiate them using stack semantics, operator new, or operator gcnew. But still, what you see is what you get.&lt;/font&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Reference types are always created on the managed heap. Even if you use stack semantics for instantiating a reference type, the compiler still allocates the object on the managed heap. The compiler then takes care to insure that the object behavior (like deterministic cleanup etc&amp;hellip;) mimics what you would expect of a stack based object.&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If you are programming C++ in a mixed mode environment (both native and managed code in the same module) it is important to be aware of these possibilities and their impact.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;C#&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;C# has a type system that is a lot easier to grasp.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Classes are reference types. They are always created on the managed heap.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Structures are value types. They are always created on the stack. C# -like C++/CLI- also supports the concept of boxing, where a copy of the value type is saved on the managed heap.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;Conclusion&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;C# and C++/CLI share some type traits. The cases that are identical in C++/CLI and C# are in the following table:&lt;/font&gt;&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse:collapse;border:medium none;"&gt;&lt;tr&gt;&lt;td style="padding-right:5.4pt;padding-left:5.4pt;padding-bottom:0cm;width:147.6pt;padding-top:0cm;background-color:transparent;border:windowtext 1pt solid;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:windowtext 1pt solid;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;C#&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:windowtext 1pt solid;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;C++/CLI&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:windowtext 1pt solid;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Value type&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;struct&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;value class&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:windowtext 1pt solid;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Reference type&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;class&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="border-right:windowtext 1pt solid;padding-right:5.4pt;border-top:#ece9d8;padding-left:5.4pt;padding-bottom:0cm;border-left:#ece9d8;width:147.6pt;padding-top:0cm;border-bottom:windowtext 1pt solid;background-color:transparent;"&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;ref struct&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;All other types in C++ and C++/CLI do not have a 100% equivalent in C#.&lt;/font&gt;&lt;/p&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;When building class libraries for use in other .NET enabled languages, you have to watch out for incompatibilities that can be caused by using C++/CLI specific types.&lt;/span&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145312" 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><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Fun with template classes: Manipulating LabVIEW arrays in C++, part 3</title><link>http://msmvps.com/blogs/vandooren/archive/2006/08/10/Fun-with-template-classes_3A00_-Manipulating-LabVIEW-arrays-in-C_2B002B002C00_-part-3.aspx</link><pubDate>Thu, 10 Aug 2006 20:45:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145299</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=145299</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145299</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/08/10/Fun-with-template-classes_3A00_-Manipulating-LabVIEW-arrays-in-C_2B002B002C00_-part-3.aspx#comments</comments><description>&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This article is a follow up of my second article on interoperability for LabVIEW arrays in C++. That article provided a method for allowing programmers to index into multi dimensional arrays like this:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;But that solution was a bit clunky. It involved 4 classes which had 5 [] operators and 2 implementations of the Resize function. There was also no support for memory access via memcpy or something else.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;After a bit of redesign, I now have an improved implementation.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;The general idea&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Functionality is now split in 2 classes. There is a CLvArrayHandlePtr class that represents the array itself, and a CLvArrayIndexer class to provide the [] operator.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;You can no longer index in the array object directly. The CLvArrayHandlePtr class is now meant solely for managing the array itself. This makes the array simpler.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The indexing functionality has been put in the CLvArrayIndexer class. Since all that class does is to provide a [] operator and an accessor for the data pointer, it is a very lightweight class that is easy to maintain.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This solution also makes it easier to add extra functionality later on as separate lightweight classes that are tailored to a specific purpose, instead of having to perform all modifications in a class that includes everything and the kitchen sink.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;The Revised Array Class&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The CLvArrayHandlePtr class is still a template class with a specialization for 1 dimensional arrays. The general principles behind the array has not been changed, so I am not going to reiterate all explanations over here. Instead, I will only explain the changes.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; T, &lt;span style="color:blue;"&gt;int&lt;/span&gt; Q=1&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CLvArrayHandlePtr&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;span style="color:green;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(&lt;span style="color:blue;"&gt;push&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(1)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; &lt;span style="color:blue;"&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;size dimSize[Q];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T data[1];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;} t_LvArray, *p_LvArray, **h_LvArray;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(&lt;span style="color:blue;"&gt;pop&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;h_LvArray* m_HandlePtr;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; Resize(size DimSize[ Q]){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t GetSize(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; GetDimSizes(size_t DimSizes[ Q]){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T* GetDataPtr(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; T&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CLvArrayHandlePtr&amp;lt;T, 1&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(&lt;span style="color:blue;"&gt;push&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(1)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; &lt;span style="color:blue;"&gt;struct&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;size_t dimSize;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T data[1];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;} t_LvArray, *p_LvArray, **h_LvArray;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;#pragma&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;pack&lt;/span&gt;(&lt;span style="color:blue;"&gt;pop&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;h_LvArray* m_HandlePtr;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; Resize(size_t DimSize){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t GetSize(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; GetDimSizes(size_t &amp;amp;DimSize){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T* GetDataPtr(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){ &amp;hellip; }&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;These classes have roughly the same methods as their previous versions. The most notable differences are:&lt;/font&gt;&lt;/p&gt;&lt;ul style="margin-top:0cm;"&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;They now use size_t for dimension sizes.&lt;/font&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;There is a function for returning the pointer to the first element in the array.&lt;/font&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 6pt;tab-stops:list 36.0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;There is a function to retrieve the dimension sizes.&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The last 2 points are necessary in order to cleanly work with the 2 new classes.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;The array indexer class&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The 2 new classes are used solely to allow indexing operations on the LabVIEW array. They have no other added functionality, so they are fairly simple.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; T, &lt;span style="color:blue;"&gt;int&lt;/span&gt; Q=1&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CLvArrayIndexer&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;private&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t m_TotalSize;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t m_DimSizes[ Q];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T *m_Data;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//create a new instance, based on an actual array.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer(CLvArrayHandlePtr&amp;lt;T, Q&amp;gt; LvArray)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_TotalSize = LvArray.GetSize();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LvArray.GetDimSizes(m_DimSizes);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_Data = LvArray.GetDataPtr();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//create a new instance, based on a data pointer and dimension sizes&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer(size_t DimSizes[ Q], T* DataPtr)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&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;Q; i++)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_DimSizes[ i] = DimSizes[ i];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_Data = DataPtr;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//return a new indexer with 1 dimension less.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer&amp;lt;T, Q-1&amp;gt; &lt;span style="color:blue;"&gt;operator&lt;/span&gt;[](size_t Index)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;size_t subDimSize = 1;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&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=1; i&amp;lt;Q; i++)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;subDimSize *= m_DimSizes[ i];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; CLvArrayIndexer&amp;lt;T, Q-1&amp;gt;(&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_DimSizes + 1,&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_Data + Index * subDimSize);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get the size of the data segment that represents this subdimension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t GetSize(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; m_TotalSize;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get the pointer to the first element of this subdimension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T* GetDataPtr(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; m_Data;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; T&amp;gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; CLvArrayIndexer&amp;lt;T, 1&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;private&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t m_TotalSize;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T *m_Data;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//create a new instance, based on an actual array.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer(CLvArrayHandlePtr&amp;lt;T, 1&amp;gt; LvArray)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_TotalSize = LvArray.GetSize();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_Data = LvArray.GetDataPtr();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//create a new instance, based on a data pointer and dimension sizes&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer(size_t DimSizes[1], T* DataPtr)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_TotalSize = DimSizes[1];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_Data = DataPtr;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//return a reference to the element at the specified index.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T&amp;amp; &lt;span style="color:blue;"&gt;operator&lt;/span&gt;[](size_t Index)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; m_Data[Index];&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get the size of the data segment that represents this subdimension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t GetSize(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; m_TotalSize;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get the pointer to the first element of this subdimension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;T* GetDataPtr(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; m_Data;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;As you can see, there are 2 constructors for creating an indexer. The first takes the original array as an argument. It uses the array methods for getting the data size and data pointers.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The second constructor takes the size and pointer directly. This is used byt CLvArrayIndexer classes that create another CLvArrayIndexer class with a lower dimension.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The [] operator itself is also pretty simple. For multi dimensional indexers, the [] operator returns a new indexer that has 1 less dimension than itself. For 1 dimensional array indexers, it returns a reference to an element inside the original array.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The trick here is that each next [] operator points to a more specific location inside the original array until 1 specific element is referenced.&lt;/font&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;font size="5"&gt;Using the array and indexer classes&lt;/font&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;To use the array and indexer classes in not very different from the previous solution.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Given an array with the following declaration:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;CLvArrayHandlePtr&amp;lt;&lt;span style="color:blue;"&gt;double&lt;/span&gt;, 3&amp;gt; Array;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Using it is done like this:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;size_t size[3] = {&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;requestCountPages,&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;requestCountRows,&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;requestCountColumns};&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Array.Resize(size);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;CLvArrayIndexer&amp;lt;&lt;span style="color:blue;"&gt;double&lt;/span&gt;, 3&amp;gt; indexer(Array);&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;double&lt;/span&gt; i=0;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&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; page=0; page&amp;lt;requestCountPages; page++)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&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; row=0; row&amp;lt;requestCountRows; row++)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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; column=0; column&amp;lt;requestCountColumns; column++)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;indexer[page][row][column] = i++;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Using the data pointer and size of a sub segment are of course as easy as&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;Memcpy(Target, indexer.GetDataPtr(), indexer.GetSize());&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1 style="margin:12pt 0cm 3pt;"&gt;&lt;span&gt;&lt;font size="5"&gt;Afterthoughts&lt;/font&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;This solution is clean, and easy to use and maintain. I am fairly happy with it.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Of course, what I am not yet happy about is the lack of error handling. For example, the indexer class does not yet check if the array is actually allocated or not. If it isn&amp;rsquo;t, then the current solution will dereference a NULL pointer.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;There is also no size checking to prevent indexers from going out of bounds.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;But as before, this code is proof of concept code. I am toying with the idea of implementing those error handlers, but I want to do it in a way that allows you to use either C style return value error handling or C++ style exception handling. &lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;One possibility is to use error handling template classes. However, That will have to wait for next time.&lt;/font&gt;&lt;/p&gt;&lt;span style="font-size:12pt;font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;The full code for the classes is available for download, together with the dll code and some LabVIEW vis for testing. Everything is licensed under the MIT license as usual.&lt;/span&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145299" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.14.52.99/LvArrayTemplate_5F00_3.zip" length="28576" 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/LabVIEW/default.aspx">LabVIEW</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Yet another contribution to the VCFAQ</title><link>http://msmvps.com/blogs/vandooren/archive/2006/08/01/Yet-another-contribution-to-the-VCFAQ.aspx</link><pubDate>Tue, 01 Aug 2006 20:43:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145293</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=145293</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145293</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/08/01/Yet-another-contribution-to-the-VCFAQ.aspx#comments</comments><description>&lt;div class="itemBodyStyle"&gt;&lt;p&gt;Did you ever encounter problems to do with the size of structures in C or C++? In that case, chances are that you had to deal with structure layout and byte packing.&lt;/p&gt;&lt;p&gt;You can read my explanation over &lt;a href="http://vcfaq.mvps.org/lang/11.htm" title="here"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145293" 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/VCFAQ/default.aspx">VCFAQ</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>The joy of receiving an MVP award</title><link>http://msmvps.com/blogs/vandooren/archive/2006/07/04/The-joy-of-receiving-an-MVP-award.aspx</link><pubDate>Tue, 04 Jul 2006 20:39:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145291</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=145291</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145291</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/07/04/The-joy-of-receiving-an-MVP-award.aspx#comments</comments><description>&lt;div class="itemBodyStyle"&gt;&lt;p&gt;Yaaaaaaay.&lt;/p&gt;&lt;p&gt;Yesterday I received a message to tell me that I received the Microsoft MVP award in the category &amp;#39;Visual C++&amp;#39;.&lt;/p&gt;&lt;p&gt;I knew I was nominated 2 months ago, which I found very cool. Of course I had to wait a bit because the anouncement of the new awardees was going to be made on the 1st of July.&lt;/p&gt;&lt;p&gt;When I didn&amp;#39;t get a mail by sunday evening (the 2nd of July) I figured I did not get the award.&lt;/p&gt;&lt;p&gt;But then I got the mail with happy news on the 3d of July. &lt;img alt=":-)" height="15" src="http://www.bdvd.be/smilies/happy.gif" width="15" /&gt;&lt;/p&gt;&lt;p&gt;Sometime soon I will receive a package with information on all things that have to do with being an MVP. I do not yet know the details, but apparently I can receive a free MSDN subscription. On top of that it is possible to get access to private Microsoft newsgroups or even to windows source code.&lt;/p&gt;&lt;p&gt;I&amp;#39;ll have to see what it all means, but it sure looks exiting.&lt;/p&gt;&lt;p&gt;My MVP profile can be found &lt;a href="https://mvp.support.microsoft.com/profile=DDDD855D-0BB4-4078-B4CE-5CF802AFB001" title="here"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145291" 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/MVP/default.aspx">MVP</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Another contribution to the VCFAC</title><link>http://msmvps.com/blogs/vandooren/archive/2006/06/18/Another-contribution-to-the-VCFAC.aspx</link><pubDate>Sun, 18 Jun 2006 20:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:145277</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=145277</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=145277</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/06/18/Another-contribution-to-the-VCFAC.aspx#comments</comments><description>&lt;div class="itemBodyStyle"&gt;&lt;p&gt;My second contribution to the VCFAQ is now online. It discusses 3 common causes of segmentation faults after upgrading a project to a newer version of Visual C++.&lt;/p&gt;&lt;p&gt;You can read it over here:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.bdvd.be/ct.ashx?id=2062dc37-9676-4083-ae0a-672f1c909d09&amp;amp;url=http%3a%2f%2fvcfaq.mvps.org%2flang%2f9.htm"&gt;http://vcfaq.mvps.org/lang/9.htm&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=145277" 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/VCFAQ/default.aspx">VCFAQ</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Is it possible to create (USB) device drivers with Visual C++?</title><link>http://msmvps.com/blogs/vandooren/archive/2006/06/15/Is-it-possible-to-create-_2800_USB_2900_-device-drivers-with-Visual-C_2B002B003F00_.aspx</link><pubDate>Thu, 15 Jun 2006 09:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:139633</guid><dc:creator>vanDooren</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=139633</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=139633</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/06/15/Is-it-possible-to-create-_2800_USB_2900_-device-drivers-with-Visual-C_2B002B003F00_.aspx#comments</comments><description>&lt;p&gt;This question pops up in the Visual C++ newsgroups from time to time.&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;strong&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;You can&amp;rsquo;t. At least, you cannot directly perform USB communications. USB simply doesn&amp;rsquo;t work that way. They same is true for PCI, Firewire, SCSI, ...&lt;/font&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;All USB IO has to be performed by a USB device driver. User space applications send IO requests to the device driver. The device driver will then perform some processing and complete the request.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The first possibility is that your USB device is of a standard device class in which case it doesn&amp;rsquo;t need a special device driver, or it needs its own device driver, but exports a standardized device interface.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;A good example of this is a USB to serial converter. The device driver registers a standardized serial interface with the system.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Any user mode application can then use the normal .NET or win32 APIs for serial communications without having to care about the fact that the serial line is in fact connected to a USB port instead of being soldered to the motherboard.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The next possibility of course is that the device is a non-standard device. In that case you cannot access it through a standard windows high level API. Normally the device manufacturer will ship a high level API (e.g. a dll or ActiveX object) with the device driver to allow you to interact with the devices.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;If no API is available, you will have to use the CreateFile, DeviceIoControl, ReadFile, WriteFile and CloseHandle functions (among others) to directly communicate with the device driver.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;Lastly, it is possible that you have a custom device of which you only have the interface documentation, but no device driver or API. In that case you need to create your own device driver. For more information on writing device drivers you can read my articles (and others on &lt;/font&gt;&lt;a href="http://www.codeproject.com/"&gt;&lt;font face="Times New Roman" size="3"&gt;www.codeproject.com&lt;/font&gt;&lt;/a&gt;&lt;font face="Times New Roman" size="3"&gt;) as a starting point:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;a href="http://www.codeproject.com/system/wdf_kmdf_basic.asp"&gt;&lt;font face="Times New Roman" size="3"&gt;http://www.codeproject.com/system/wdf_kmdf_basic.asp&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;a href="http://www.codeproject.com/system/kmdf_osr_usb_fx2.asp"&gt;&lt;font face="Times New Roman" size="3"&gt;http://www.codeproject.com/system/kmdf_osr_usb_fx2.asp&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;The first article explains all the steps involved in actually creating a device driver. The second article explains all the issues in programming a fully functional USB device driver. Both articles use the Microsoft&amp;rsquo;s new KMDF framework. It is relatively easy to learn if you have C/C++ experience.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;There are some other toolkits available from 3d parties, but they cost money, and a bigger problem is that they are non-standard so you cannot ask other developers for support unless they use the same toolkit. Another problem is that the vendor might discontinue the toolkit, and leave you with nothing but unsupported software.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;In any case, as soon as you need to develop a device driver you should not use VC++. Use the DDK build tools instead. They are the standard when it comes to building device drivers, and you can get good support on microsoft.public.development.device.drivers.&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;You can download the latest KMDF DDK here:&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;"&gt;&lt;a href="http://www.microsoft.com/whdc/driver/wdf/KMDF.mspx"&gt;&lt;font face="Times New Roman" size="3"&gt;http://www.microsoft.com/whdc/driver/wdf/KMDF.mspx&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=139633" 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/Driver+programming/default.aspx">Driver programming</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item></channel></rss>