Menu

#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

  • Nikita Perestoronin

    Build 218 is used.

     
  • Nikita Perestoronin

    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)

     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.