Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#622 Dynamic dispatch and passing arguments by reference

open
nobody
com (105)
5
2012-11-29
2012-11-29
No

I have the following problem when calling methods that accept arguments passed by reference.

Consider the following code:

import win32com.client
import pythoncom
sldworks = win32com.client.gencache.EnsureModule('{83A33D31-27C5-11CE-BFD4-00400513BB57}', 0, 21, 0)
swconst = win32com.client.gencache.EnsureModule('{4687F359-55D0-4CD3-B6CF-2EB42C11F989}', 0, 21, 0)
sw = sldworks.SldWorks()
model_path = 'C:\Demo\model.SLDPRT'
model, errors, warnings = sw.OpenDoc6(model_path, swconst.constants.swDocPART, swconst.constants.swOpenDocOptions_Silent, '', pythoncom.Missing, pythoncom.Missing)
ext = model.Extension

In case of static dispatch it works correctly:

>>> ext
>>> <win32com.gen_py.SldWorks 2013 Type Library.IModelDocExtension instance at 0x206388400>
>>> ext.GetAdvancedSpotLightProperties('Ambient')
>>> (0.0, 1.0, 0.0, 0.0)

In case of dynamic dispatch it sets wrong value for the last argument:

dext = win32com.client.dynamic.DumbDispatch(ext)
arg1 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
arg2 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
arg3 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
arg4 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)

>>> dext
>>> <COMObject <unknown>>
>>> dext.GetAdvancedSpotLightProperties('Ambient', arg1, arg2, arg3, arg4)
>>> arg1.value, arg2.value, arg3.value, arg4.value
>>> (0.0, 1.0, 0.0, u'Ambient')

I've checked more methods in SolidWorks API: in case of dynamic dispatch, when arguments are passed by reference, value of the last argument equals to the value of the first argument after call.

Since pywin32 fails to provide static dispatch object in some cases,
(for example, if I call model.SelectionManager, it returns <COMObject SelectionManager>),
I can't use some methods in SolidWorks API.

Discussion

  • Build 218 is used.

     
  • I seems that arguments are written in reverse order.
    Possible hack is to pass all arguments by reference and reverse them after:

    arg0 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, 'Ambient')
    arg1 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
    arg2 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
    arg3 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)
    arg4 = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_R8, 0.0)

    >>> dext.GetAdvancedSpotLightProperties(arg0, arg1, arg2, arg3, arg4)
    >>> arg3.value, arg2.value, arg1.value, arg0.value
    >>> (0.0, 1.0, 0.0, 0.0)