enthought / enthought/comtypes
Error setting a value on VARIANT out param
- Dominant language
- Python
- Stars
- 345
- Forks
- 105
- PR merge metrics
- No merged PRs in 30d
Description
Some `VARIANT` out params are not initialised before being passed to a callback, setting these to a value results in `WindowsError: [Error -2147352568] Bad variable type` because comtypes attempts to clear the variant before setting the value.
Our situation:
- Setting up an `accPropServer`, with [method `GetPropValue`](https://docs.microsoft.com/en-us/windows/win32/api/oleacc/nf-oleacc-iaccpropserver-getpropvalue)
- the `VARIANT` out param `pVarValue` has not been initialised (at least on my version of Windows Version `1903` Build `18362.239`).
- Setting a value on this `VARIANT` results in `automation.py` calling `_VariantClear` prior to setting the value. This leads to the "bad variable type" error and then also the issue fixed with https://github.com/enthought/comtypes/pull/187.
- When using a high level callback function, returning the out params, there is no way to initialise the out params before setting a value.
We have worked around this issue with https://github.com/nvaccess/nvda/pull/9900
Our work around is to use a low level callback, and initialise the out param `VARIANT` before assigning a value. Note this is [what the Microsoft sample does.](https://docs.microsoft.com/en-us/windows/win32/winauto/server-annotation-sample)
Setting the accPropServer:
``` Python
from IAccessibleHandler import accPropServices
accPropServices.SetHwndPropServer(
hwnd=self.hwnd,
idObject=winUser.OBJID_CLIENT,
idChild=0,
paProps=self.properties_GUIDPTR,
cProps=len(self.properties_GUIDPTR),
pServer=self,
AnnoScope=ANNO_CONTAINER if annotateChildren else ANNO_THIS
)
```
Initialise the `VARIANT` before setting a value in the `GetPropValue`.
``` Python
def GetPropValue(
self, this, # unused "this" used to indicate to comTypes we want a low level implementation
pIDString: str,
dwIDStringLen: int,
idProp: GUID,
pvarValue: POINTER(VARIANT),
pfGotProp: POINTER(BOOL)
) -> int:
try:
# Preset values for "no prop value", in case we return early.
pfGotProp.contents.value = self.DOES_NOT_HAVE_PROP
_VariantInit(pvarValue)
```
To fix this in comtypes, inspect the code in `_comobjec.py` in functions `hack`, `call_with_this`, and `call_without_this`. Out params of type `VARIANT` should be initialised with `_VariantInit`. Note: inout params should not be initialised, as it is expected that they contain valid arguments.
Contributor guide
Assessment
This issue has not been assessed yet.