<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Christopher Eck's Old Unused Blog</title><link>http://blogs.msdn.com/chriseck/default.aspx</link><description>I've left the CLR team.</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Malicious Software Removal</title><link>http://blogs.msdn.com/chriseck/archive/2005/01/11/350887.aspx</link><pubDate>Tue, 11 Jan 2005 17:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:350887</guid><dc:creator>chriseck</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chriseck/comments/350887.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chriseck/commentrss.aspx?PostID=350887</wfw:commentRss><description>&lt;p&gt;Sorry it's been so long since I've last posted.&amp;nbsp; A large vacation coupled with some serious medical issues in my family and prevented me getting around to it.&amp;nbsp; And I got married :)&lt;/p&gt; &lt;p&gt;So, just a quick entry today to get back into the swing of things.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Microsoft has finally released the "Malicious Software Removal Tool"!&amp;nbsp; Check it out at &lt;a href="http://www.microsoft.com/security/malwareremove/default.mspx"&gt;http://www.microsoft.com/security/malwareremove/default.mspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;What's better is that there is a promised monthly update schedule in place.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;For my next few entries, I plan on&amp;nbsp;addressing topics such as: continuing the discussion on RCWs and CCWs, new interop features in Whidbey, marshaling performance, and debugging tips and tricks.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=350887" width="1" height="1"&gt;</description></item><item><title>How do COM objects interact with the CLR type system?  (cont.)</title><link>http://blogs.msdn.com/chriseck/archive/2004/11/11/255806.aspx</link><pubDate>Thu, 11 Nov 2004 15:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:255806</guid><dc:creator>chriseck</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/chriseck/comments/255806.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chriseck/commentrss.aspx?PostID=255806</wfw:commentRss><description>&lt;p&gt;Today, I'll continue my discussion on how COM objects interact with the CLR type system by talking about consuming COM objects from managed code in a late bound fashion.&amp;nbsp; Sorry there is no example code included in this one, but I'm in a hurry :)&lt;/p&gt; &lt;p&gt;As defined in my last post, late binding refers to access and use of a type that is not known at compile time.&amp;nbsp; Note that there is a difference in compile-time late binding and late-bound method invocation.&amp;nbsp; The former refers to knowledge of the type at compile time while the latter refers to how methods are invoked on an object at runtime.&amp;nbsp; I'll cover both of these below.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;How do I get an instance at runtime that represents a COM object?&lt;/p&gt; &lt;p&gt;First, I'll mention that if the metadata for a COM object is not available, the CLR will substitute the type with System.__ComObject, a generic type that provides no methods and acts as a representative for a non-strongly typed COM object.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;1) You could use PInvoke to call into the IClassFactory for the object.&lt;/p&gt; &lt;p&gt;2) You could use Type.GetTypeFromCLSID to get a managed type object which represents the COM object's type.&amp;nbsp; You could then activate an instance of this type with Activator.CreateInstance.&lt;/p&gt; &lt;p&gt;3) You could use Marshal.GetTypeForITypeInfo to get a managed type object which represents the COM object's type.&amp;nbsp; This API is interesting in that it will automatically import the matching type library (if available) and create an IA on the fly.&amp;nbsp; You will not get the generic System.__ComObject out of this API if the type library is available.&amp;nbsp; Just as above, you can activate an instance of this type with Activator.CreateInstance.&lt;/p&gt; &lt;p&gt;4) You could receive an instance of a COM object as a return or out/ref parameter of another call to or from native code.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;Now you have a runtime generated type.&amp;nbsp; Depending on which API and method you used you will either have a strongly typed object or the generic System.__ComObject.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;To call methods on this object, you'll end up having to cast the object to a real type, or use Type.InvokeMember since the compiler didn't know what type you were using when it emitted IL.&amp;nbsp; For COM objects, Type.InvokeMember will marshal the arguments to their native versions, get the object's IDispatch interface, and call IDispatch::Invoke.&amp;nbsp; This is the same path taken for strongly typed COM objects that only allow late-bound method invocation (in other words, for COM objects that don't supply a vtable and only allow calls via IDispatch).&lt;/p&gt; &lt;p&gt;VB actually calles Type.InvokeMember under the covers for you for late-bound types.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;Any call that goes through IDispatch::Invoke indicates late-bound invocation on a COM object.&lt;br /&gt;Any call that goes through Type.InvokeMember indicates late-bound invocation on a managed object (which could be a RCW placeholder object in which case we'll end up going through IDispatch::Invoke).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Next time, I'll be covering calls from COM into the CLR...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=255806" width="1" height="1"&gt;</description></item><item><title>Bug Triage Process</title><link>http://blogs.msdn.com/chriseck/archive/2004/10/26/248309.aspx</link><pubDate>Tue, 26 Oct 2004 23:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:248309</guid><dc:creator>chriseck</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chriseck/comments/248309.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chriseck/commentrss.aspx?PostID=248309</wfw:commentRss><description>&lt;p&gt;Ever wanted to see what a Microsoft bug triage process looks like?&lt;/p&gt; &lt;p&gt;Here is a video recorded bug triage from the MSBuild team in my division:&lt;/p&gt; &lt;p&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=26641"&gt;http://channel9.msdn.com/ShowPost.aspx?PostID=26641&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=248309" width="1" height="1"&gt;</description></item><item><title>How do COM objects interact with the CLR type system?</title><link>http://blogs.msdn.com/chriseck/archive/2004/10/25/247755.aspx</link><pubDate>Tue, 26 Oct 2004 02:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:247755</guid><dc:creator>chriseck</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/chriseck/comments/247755.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chriseck/commentrss.aspx?PostID=247755</wfw:commentRss><description>&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;This is a question that actually covers a lot of ground in the VM, so I’ll be discussing this in parts over my next few entries.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I highly recommend reading the information located under this node in the online MSDN documentation:&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconadvancedcominterop.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconadvancedcominterop.asp&lt;/a&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;I also highly recommend &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:PersonName w:st="on"&gt;Adam Nathan&lt;/st1:PersonName&gt;’s “.NET and COM: The Complete Interoperability Guide”.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;(ISBN# &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;067232170X&lt;/span&gt;)&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;We’ll start by looking at consuming COM objects from managed code in an early-bound fashion.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Early-bound means that we have knowledge about the object in question, so we’ll tell the CLR about our COM object at compile-time.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Late-bound means that we’ll do everything programmatically at run-time and don’t need information about the object up front; this is obviously more time consuming as we need to perform much of the work at run-time that the early-bound case handles at compile-time.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It’s not a great idea in perf-critical situations if you can help it.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Since the CLR’s type system is completely dependent on metadata (contents of the assembly including types, methods, fields, attributes, offsets, etc.), we’ll need to provide a metadata ‘view’ of our COM object so the compiler knows what to bind to.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Fortunately, most COM Objects already provide type information in type libraries; so we simply import that existing type library into the CLR’s metadata format via the sdk tool TlbImp or VS’s “Add a Reference”.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Alternatively, one might decide to author the metadata from scratch, though this is a tedious and error-prone process.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Either way, the resulting assembly is called an &lt;i style="mso-bidi-font-style: normal"&gt;Interop Assembly&lt;/i&gt; (IA).&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Due to the lack of information for certain constructs in type libraries, there are cases where the information must be added by hand to the IA after it has been built.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;A common case I run into fairly often is the IDL attribute size_is which can define the size of an array with another parameter:&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;HRESULT Proc1(&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[in] short m;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[in, size_is(m)] short a[]);&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;// If m = 10, a[10]&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Once compiled by the MIDL compiler into a type library, this looks like:&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;HRESULT Proc1(&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[in] short m;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[in] short a[]);&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;When TlbImp is run over the type library to create an IA, it doesn’t know about the size_is attribute as it is not present in the type library.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Therefore, this information would need to be added to the IA by hand.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I’ll detail these cases further if I see some interest on the subject.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;The IA contains managed definitions representing native types, so now managed languages can treat these types as any other managed types.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The definitions themselves have special attributes that tell the CLR that these actually represent COM objects and should be treated specially at run-time, but this is all transparent at compile time.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;As an example, importing the standard stdole32.tlb gives the following metadata (dumped via ILDasm) for IEnumVARIANT:&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;.class interface public abstract auto ansi import stdole.IEnumVARIANT&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;.custom instance void [mscorlib]System.Runtime.InteropServices.InterfaceTypeAttribute::.ctor(int16) = &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;( 01 00 01 00 00 00 )&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;( 01 00 24 30 30 30 32 30 34 30 34 2D 30 30 30 30 2D 30 30 30 30 2D 43 30 30 30 2D 30 30 30 &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30 30 30 30 30 30 30 34 36 00 00 ) // ..$00020404-0000-0000-C000-000000000046..&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;} // end of class stdole.IEnumVARIANT&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;The important attributes to note are the ComImport (shown as “import” above) and the addition of two custom attributes on the class, InterfaceType and Guid.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;ComImport tells the CLR that this type is actually defined in native code and was imported for use with a RCW.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;InterfaceType indicates what type of interface this represents (early-bound, late-bound or both).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Guid is the native GUID of this interface.&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;/p&gt; &lt;p&gt;&lt;br style="PAGE-BREAK-BEFORE: always" clear="all" /&gt;&lt;/p&gt;&lt;/span&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;I’ll use the following IL snippet as an example in the next section:&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;newobj&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; &lt;/span&gt;instance void [COMSERVERLib]COMSERVERLib.FooClass::.ctor()&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;stloc.1&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;ldloc.1&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;stloc.2&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;ldloc.2&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;callvirt &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;instance string [COMSERVERLib]COMSERVERLib.IFoo::GetFoo()&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;stloc.3&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;ldloc.2&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;castclass&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[SomeOtherIA]SomOtherIA.IBar&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;o:p&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee" color="#660000"&gt;&amp;nbsp;&lt;/font&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;At run-time, the COM object is typically instantiated by calling &lt;i style="mso-bidi-font-style: normal"&gt;newobj&lt;/i&gt; on the type contained in the IA (this corresponds to C#’s &lt;i style="mso-bidi-font-style: normal"&gt;new &lt;/i&gt;operator and similarly named operators in other languages).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Instead of going down the normal creation path for objects, however, the CLR recognizes the attributes on the type and instantiates the COM object.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Once the COM object has been created, the CLR creates a place-holder object using the metadata in the IA (so that reflection has access to the list of static interfaces implemented by the object and described in the IA), and a backing construct called a &lt;i style="mso-bidi-font-style: normal"&gt;Runtime Callable Wrapper&lt;/i&gt; (RCW).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The RCW and the place-holder object are linked together and the caller is returned the place-holder object which appears to be a standard managed object.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;newobj&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; &lt;/span&gt;instance void [COMSERVERLib]COMSERVERLib.FooClass::.ctor()&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;This IL snippet shows creation of a COM object “FooClass” defined in IA “COMSERVERLib.dll”.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;The RCW is the interesting structure here...it contains the pointer to the COM object, maintains a reference to the COM object (AddRefs once each time the object enters the CLR), a cache of specific interface pointers on the object, marshaling characteristics of the object, and other auxiliary information.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It is interesting to note that the CLR maintains a one-to-one relationship between unique COM object pointers and RCWs in a given AppDomain.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Whenever a call/callvirt is made on the place-holder object, the call instruction is intercepted by the RCW and a call is made on the underlying COM object.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Depending on how complex the arguments of the signature are, the 32-bit CLR will either create a compiled x86 stub to handle marshaling of the types or will delegate to a slower interpreted path that can handle the more complex types that the marshaler knows about.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The 64-bit CLR employs a different mechanism called &lt;i style="mso-bidi-font-style: normal"&gt;IL Stubs&lt;/i&gt;; here we create an IL stream to handle the marshaling and let the JIT compile it appropriately.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;callvirt &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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;instance string [COMSERVERLib]COMSERVERLib.IFoo::GetFoo()&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;This IL snippet shows a call on the COM object instantiated above.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;While it appears identical to a callvirt to a managed interface, the CLR will intercept and make the call on the underlying COM object.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Casting on RCW-based objects is handled differently from normal mananged objects.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;For interface casting, the CLR first checks the metadata for a ‘static’ interface match…that is, that the interface being cast to is already listed in the metadata from the IA.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If this fails we fall back on the COM notion of casting – calling QueryInterface.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;We’ll determine the GUID of the interface being cast to and then call QI on the underlying pUnk with that GUID – if it succeeds, then we cache the result and the cast is successful.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;This is interesting as we could have no interfaces listed in the metadata (which means typeof(MyComClass).GetInterfaces() returns no interfaces), but still have successful casts.&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;font color="#660000"&gt;&lt;font style="BACKGROUND-COLOR: #eeeeee"&gt;castclass&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[SomeOtherIA]SomeOtherIA.IBar&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;This IL snippet shows a cast on the RCW-based object instantiated above to an interface defined in a different assembly.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If the COMSERVERLib IA lists SomeOtherIA.IBar in FooClass’s list of implemented interfaces, then this cast will look at the associated metadata and succeed immediately.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If it does not list IBar, then the underlying COM object will be QI’d for the IBar interface.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=247755" width="1" height="1"&gt;</description></item></channel></rss>