mhammond / pywin32

Python for Windows (pywin32) Extensions
4.9k stars 783 forks source link

Need help to implement support for record pointers as method parameters. #2304

Open geppi opened 5 days ago

geppi commented 5 days ago

With a COM Dual Interface it is possible to get server side changes to record members marshaled back to the client when the type library specifies a record pointer as the interface method parameter.

The Python comtypes package supports this for custom COM interfaces and the support for iDispatch was recently added with PR#535.

Pywin32 does currently not support this and seems to pass a record parameter "by value" to the type library marshaler. Therefore COM server side changes to record members are not marshaled back to the client and the record stays unmodified on the client side.

I tried to figure out what changes to pywin32 would be required to implement this support but am a little lost because the mechanics of the package seems to be way more complex than that of the comtypes package.

I would appreciate hints on where and how this support could be implemented. From a first look it seems to me that the issue starts in com/win32com/client/build.py line 533:

        if indir_vt == pythoncom.VT_PTR:
            # If it is a VT_PTR to a VT_USERDEFINED that is an IDispatch/IUnknown,
            # then it resolves to simply the object.
            # Otherwise, it becomes a ByRef of the resolved type
            # We need to drop an indirection level on pointer to user defined interfaces.
            # eg, (VT_PTR, (VT_USERDEFINED, somehandle)) needs to become VT_DISPATCH
            # only when "somehandle" is an object.
            # but (VT_PTR, (VT_USERDEFINED, otherhandle)) doesn't get the indirection dropped.
            was_user = (
                isinstance(subrepr, tuple) and subrepr[0] == pythoncom.VT_USERDEFINED
            )
            subrepr, sub_clsid, sub_doc = _ResolveType(subrepr, itypeinfo)
            if was_user and subrepr in [
                pythoncom.VT_DISPATCH,
                pythoncom.VT_UNKNOWN,
                pythoncom.VT_RECORD,
            ]:
                # Drop the VT_PTR indirection
                return subrepr, sub_clsid, sub_doc

However, I have currently no idea what implications this has, if C++ code would have to be changed and how much effort it would be to handle pointers to User Defined Types as COM method parameters.