<?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>yalvi's WebLog</title><link>http://blogs.msdn.com/yalvi/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>VariantWrapper</title><link>http://blogs.msdn.com/yalvi/archive/2005/02/18/376381.aspx</link><pubDate>Fri, 18 Feb 2005 23:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:376381</guid><dc:creator>yalvi</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/yalvi/comments/376381.aspx</comments><wfw:commentRss>http://blogs.msdn.com/yalvi/commentrss.aspx?PostID=376381</wfw:commentRss><description>&lt;p&gt;&amp;nbsp;&amp;nbsp; In versions 1.0 and 1.1 of the .NET Framework, there was no way to pass a Variant of type VT_VARIANT | VT_BYREF to native code through PInvoke or COM Interop.&amp;nbsp; The Interop layer would extract the actual type being passed to native and use the matching Variant type to create the marshaled Variant e.g. a string would always be passed as a VT_BSTR, an Int32 would always be passed as a VT_I4 and so on.&amp;nbsp; During implementation of version 2.0, we (the CLR Interop team) received quite a few customer requests asking us to add this support.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp; One use of passing VT_VARIANT | VT_BYREF Variants is that the actual type of the Variant can be changed by the callee e.g. a Variant of type (VT_VARIANT | VT_BYREF)=&amp;gt;VT_DATE passed in such a manner can be changed to any valid Variant type on the native side i.e. (VT_VARIANT | VT_BYREF)=&amp;gt;VT_*.&amp;nbsp; Supporting this scenario is especially important for MFC COM objects since the MFC IDispatch implementation explicitly checks for (VT_VARIANT | VT_BYREF) flags on every parameter declared as a VARIANT*.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp; So in version 2.0 and SP1 of version 1.1 the Interop team added a VariantWrapper class (to the System.Runtime.InteropServices namespace) to provide support for this scenario.&amp;nbsp; Below are code snippets for the various usage scenarios---(1) latebinding to COM through reflection in C#, (2) implicit latebinding to COM in VB.NET and (3) calling a disponly COM interface in C# (the actual call made by the runtime is an IDispatch call):&lt;u&gt;&lt;/u&gt;&lt;/p&gt; &lt;p&gt;&lt;u&gt;(1) Late binding&amp;nbsp;in C#&lt;br /&gt;&lt;/u&gt; &lt;div class="codeblock"&gt;//&amp;nbsp;calling COMType::ChangeVariantTypeToBSTR(VARIANT* pv);&lt;br /&gt;Object[] params = new Object[1];&lt;br /&gt;params[0] = new VariantWrapper(4);&lt;br /&gt;ParameterModifier[] pms = new ParameterModifier[1];&lt;br /&gt;ParameterModifier pm = new ParameterModifier(1);&lt;br /&gt;pm[0] = true; // pass the 1st argument by reference&lt;br /&gt;pms[0] = pm; // add pm to the array of modifiers &lt;br /&gt;// (VT_VARIANT | VT_BYREF)=&amp;gt;VT_I4 passed to COM method &lt;br /&gt;COMType.InvokeMember("ChangeVariantTypeToBSTR",...,params,pms,...);&lt;br /&gt;// COM method changes the type from VT_I4 to VT_BSTR so after the call params[0] is a string &lt;br /&gt;String retString = params[0];&lt;/div&gt;&lt;br /&gt;Note that the ParameterModifier class is used to specify ByRef semantics for any parameter of type VariantWrapper (passed latebound in this manner).&lt;br /&gt;&lt;br /&gt;&lt;u&gt;(2) VB.NET implicit late binding&lt;/u&gt;&amp;nbsp;&lt;br /&gt; &lt;div class="codeblock"&gt;' calling COMType::ChangeVariantTypeToBSTR(VARIANT* pv);&lt;br /&gt;Object o = new VariantWrapper(4)&amp;nbsp;&lt;br /&gt;' (VT_VARIANT | VT_BYREF)=&amp;gt;VT_I4 passed to COM method &lt;br /&gt;COMType.ChangeVariantTypeToBSTR(o)&lt;br /&gt;' COM method changes the type from VT_I4 to VT_BSTR so after the call 'o' is a string &lt;br /&gt;String retString = o &lt;/div&gt;&lt;br /&gt;Note that VB.NET adds ByRef semantics automatically for every implicit late binding call. Also note that ''o' is declared as an Object and not a VariantWrapper since the runtime Interop layer will not re-wrap the passed in parameter on the return trip from native. After the call, 'o' is whatever type the Variant was changed to on the native side (or the original type that was wrapped if no change is made on the native side).&lt;br /&gt;&lt;br /&gt;&lt;u&gt;(3) Calling COM method on a Disponly interface with early binding syntax in C#&lt;/u&gt;&amp;nbsp;&lt;br /&gt; &lt;div class="codeblock"&gt;// calling COMType::ChangeVariantTypeToBSTR(VARIANT* pv);&lt;br /&gt;Object o = new VariantWrapper(4);&amp;nbsp;&lt;br /&gt;// (VT_VARIANT | VT_BYREF)=&amp;gt;VT_I4 passed to COM method &lt;br /&gt;COMType.ChangeVariantTypeToBSTR(ref o);&lt;br /&gt;// COM method changes the type from VT_I4 to VT_BSTR so after the call 'o' is a string &lt;br /&gt;String retString = o' &lt;/div&gt;&lt;br /&gt;Note that in this scenario the ref keyword is required to specify ByRef semantics for any parameter of type VariantWrapper.&lt;br /&gt;&lt;br /&gt;The VariantWrapper class does have its limitations with respect to its use in Interop:&lt;br /&gt;&lt;br /&gt;Early binding is not supported.&amp;nbsp; An ArgumentException is thrown if an attempt is made to use the class in earlybound calls to native code.&lt;br /&gt;Nesting of VariantWrappers is not supported i.e. VariantWrappers cannot wrap other VariantWrappers.&amp;nbsp; Note that wrapping other wrappers in VariantWrappers is allowed e.g. VariantWrapper(DispatchWrapper(someClass)).&lt;br /&gt;VariantWrapper structure fields are not supported.&lt;br /&gt;Arrays of VariantWrappers are not allowed.&amp;nbsp; An ArgumentException is thrown if an attempt is made to use a VariantWrapper array in calls to native code.&lt;br /&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=376381" width="1" height="1"&gt;</description></item><item><title>Introduction</title><link>http://blogs.msdn.com/yalvi/archive/2005/02/18/376229.aspx</link><pubDate>Fri, 18 Feb 2005 22:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:376229</guid><dc:creator>yalvi</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/yalvi/comments/376229.aspx</comments><wfw:commentRss>http://blogs.msdn.com/yalvi/commentrss.aspx?PostID=376229</wfw:commentRss><description>Welcome to my blog! My name is Yasir Alvi and I work on the Managed Services team of the CLR. My primary focus is on Interop and Remoting Infrastructure. I plan to use this space to provide more information on topics and features in these areas that are not as well known (or documented). I’ll also try to cover issues that we frequently get questions about.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=376229" width="1" height="1"&gt;</description></item></channel></rss>