enthought / enthought/comtypes

Feature Request: Structs as valid variant types

Open
#100 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
345
Forks
105
PR merge metrics
No merged PRs in 30d

Description

Please close if feature requests are not supported here. I would be happy to submit a pull request for the above feature.

Currently, converting variants of structs with heterogeneous types is doable, although the documentation is poor and the methods are somewhat tricky, and the data returned is often much longer than desired, as well as incoherent.

This is since the variant assumes the type of the first item within the first struct, so the following struct would assume all items are doubles, even though x and y are both longs.

```
struct Data {
double value;
long x;
long y;
};
```

To fix this, you can do the following:

```
import comtypes
import ctypes

class Data(ctypes.Structure):
_fields_ = [('value', ctypes.c_double),
('x', ctypes.c_long),
('y', ctypes.c_long)]

def to_struct(variant, struct):
'''
Convert variant array of structs to tuple of structs.

Args:
variant (VARIANT): filled VARIANT
struct (Structure): struct with _fields_
'''

safe_array = comtypes.safearray._midlSAFEARRAY(struct)
return ctypes.cast(variant._.pparray, safe_array).unpack()

data = comtypes.automation.VARIANT()
size = ctypes.c_long()

com_object.GetData(data, size)
items = to_struct(data, Data)[:size.value]
```

This fixes the above issue, which I propose could be fixed using a VARIANT.vt_from_struct classmethod. The object size could by acquired from VARIANT._.pparray, allowing the full functionality above using a very clean interface.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.