Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
variant.html163 linesDownload Raw Back to HTML
1<HTML>2<HEAD>3    <TITLE>win32com.client.VARIANT</TITLE>4</HEAD>5<BODY>6 7<H2>Introduction</H2>8<p>9win32com attempts to provide a seamless COM interface and hide many COM 10implementation details, including the use of COM VARIANT structures.  This 11means that in most cases, you just call a COM object using normal Python 12objects as parameters and get back normal Python objects as results.13</p>14 15<p>16However, in some cases this doesn't work very well, particularly when using17"dynamic" (aka late-bound) objects, or when using "makepy" (aka early-bound)18objects which only declare a parameter is a VARIANT.19</p>20 21<p>22The <code>win32com.client.VARIANT</code> object is designed to overcome these 23problems.24</p>25 26<h2>Drawbacks</h2>27The primary issue with this approach is that the programmer must learn more 28about COM VARIANTs than otherwise - they need to know concepts such as 29variants being <em>byref</em>, holding arrays, or that some may hold 32bit 30unsigned integers while others hold 64bit signed ints, and they need to 31understand this in the context of a single method call.  In short, this is32a relatively advanced feature.  The good news though is that use of these33objects should never cause your program to hard-crash - the worst you should34expect are Python or COM exceptions being thrown.35 36<h2>The VARIANT object</h2>37 38The VARIANT object lives in <code>win32com.client</code>.  The constructor 39takes 2 parameters - the 'variant type' and the value.  The 'variant type' is 40an integer and can be one or more of the <code>pythoncom.VT_*</code> values,41possibly or'd together.42 43<p>For example, to create a VARIANT object which defines a byref array of 4432bit integers, you could use:45 46<pre>47>>> from win32com.client import VARIANT48>>> import pythoncom49>>> v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_I4,50...             [1,2,3,4])51>>> v52win32com.client.VARIANT(24579, [1, 2, 3, 4])53>>>54</pre>55 56This variable can then be used whereever a COM VARIANT is expected.57 58<h2>Example usage with dynamic objects.</h2>59 60For this example we will use the COM object used for win32com testing, 61<code>PyCOMTest.PyCOMTest</code>.  This object defines a method which is62defined in IDL as:63<pre>64HRESULT DoubleInOutString([in,out] BSTR *str);65</pre>66 67As you can see, it takes a single string parameter which is also used as68an "out" parameter - the single parameter will be updated after the call.69The implementation of the method simply "doubles" the string.70 71<p>If the object has a type-library, this method works fine with makepy72generated support.  For example:73 74<pre>75>>> from win32com.client.gencache import EnsureDispatch76>>> ob = EnsureDispatch("PyCOMTest.PyCOMTest")77>>> ob.DoubleInOutString("Hello")78u'HelloHello'79>>>80</pre>81 82However, if makepy support is not available the method does not work as83expected.  For the next example we will use <code>DumbDispatch</code> to84simulate the object not having a type-library.85 86<pre>87>>> import win32com.client.dynamic88>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")89>>> ob.DoubleInOutString("Hello")90>>>91</pre>92 93As you can see, no result came back from the function.  This is because94win32com has no type information available to use, so doesn't know the95parameter should be passed as a <code>byref</code> parameter.  To work96around this, we can use the <code>VARIANT</code> object.97 98<p>The following example explicitly creates a VARIANT object with a99variant type of a byref string and a value 'Hello'.  After making the100call with this VARIANT the value is updated.101 102<pre>103>>> import win32com.client.dynamic104>>> from win32com.client import VARIANT105>>> import pythoncom106>>> ob = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")107>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")108>>> variant.value # check the value before the call.109'Hello'110>>> ob.DoubleInOutString(variant)111>>> variant.value112u'HelloHello'113>>>114</pre>115 116<h2>Usage with generated objects</h2>117 118In most cases, objects with makepy support (ie, 'generated' objects) don't 119need to use the VARIANT object - the type information means win32com can guess120the right thing to pass.  However, in some cases the VARIANT object can still121be useful.122 123Imagine a poorly specified object with IDL like:124 125<pre>126HRESULT DoSomething([in] VARIANT value);127</pre>128 129But also imagine that the object has a limitation that if the parameter is an 130integer, it must be a 32bit unsigned value - any other integer representation131will fail.132 133<p>If you just pass a regular Python integer to this function, it will 134generally be passed as a 32bit signed integer and given the limitation above,135will fail.  The VARIANT object allows you to work around the limitation - just136create a variant object <code>VARIANT(pythoncom.VT_UI4, int_value)</code> and 137pass that - the function will then be called with the explicit type you 138specified and will succeed.139 140<p>Note that you can not use a VARIANT object to override the types described141in a type library.  If a makepy generated class specifies that a VT_UI2 is 142expected, attempting to pass a VARIANT object will fail.  In this case you 143would need to hack around the problem.  For example, imagine <code>ob</code>144was a COM object which a method called <code>foo</code> and you wanted to 145override the type declaration for <code>foo</code> by passing a VARIANT.146You could do something like:147 148<pre>149>>> import win32com.client.dynamic150>>> from win32com.client import VARIANT151>>> import pythoncom152>>> dumbob = win32com.client.dynamic.DumbDispatch(ob)153>>> variant = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Hello")154>>> dumbob.foo(variant)155</pre>156 157The code above converts the makepy supported <code>ob</code> into a158'dumb' (ie, non-makepy supported) version of the object, which will then159allow you to use VARIANT objects for the problematic methods.160 161</BODY>162</HTML>163 
codekingpro/portable-devtools · Team Ai