-
-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KeyError: <class 'ctypes.HRESULT'>, _ctype_to_vartype, HRESULT: VT_HRESULT #668
Comments
Thank you for your report. There are a few things I need clarification on first, so I would appreciate it if you could provide more details.
P.S. I’d appreciate it if you could highlight code and stack traces using the method described in "Creating and highlighting code blocks". |
Thank you for your quick reply. Here the link to the git with a minimal reproducer as well as the gen folder content: The COM library is related to https://www.heidenhain.us/ and used to connect to their CNC controls. |
Thank you for providing an excellent reproducer. The changes to To better understand the impact of this change, could you test the behavior of Based on the methods definition lines of the from ctypes import HRESULT, byref
from comtypes.automation import _midlSAFEARRAY
import comtypes.client
comtypes.client.GetModule((comtypes.GUID("{14B95319-AEF9-492A-A878-CA18FEB1F5BF}"), 1, 7))
import comtypes.gen.HeidenhainDNCLib as HeidenhainDNCLib
jhdaccess = comtypes.client.CreateObject(HeidenhainDNCLib.JHDataAccess, interface=HeidenhainDNCLib.IJHDataAccess4)
sa_type = _midlSAFEARRAY(HRESULT)
arr_lock = sa_type.create([])
arr_unlock = sa_type.create([])
jhdaccess.LockConfig(["Idents", "To", "Lock"], byref(arr_lock)) # first parameter is example
jhdaccess.UnlockConfig(["Idents", "To", "Unlock"], byref(arr_unlock)) # first parameter is example
print(arr_lock)
print(arr_unlock) |
I updated the git with your sample code (data_access_01.py) and the result of it (data_access_01.md). I further added a sample code (data_access_02.py) which show how I can successfully use the IJHDataAccess4 interface. Hope the result does make sense to you. Please let me know if I can test something further: |
Let us focus on the inherent peculiarity of To the best of my knowledge, if simply a 32-bit integer type is required, Even if the purpose is to check the success or failure of a method, I have not encountered a case where a parameter with flags like That said, the world of source code often contains many elements that don’t align with the "ideal" design. If you know of any use cases for Even if no such use cases are found, I believe it’s possible to derive a better solution. (Note: Please bear in mind that some COM methods, like |
I was not aware of the IJHDataAccess4.LockConfig method since it is not (yet) documented. Once it gets documented from Heidenhain, I will be able to test it. Right know I just don't know how the bstrIdentsToLock has to lock like. I do have a working sample code (data_access_04.py) which suits my needs.
|
Thank you very much for your help. |
I think using However, since it references a private element starting with For _ctype_to_vartype: Dict[Type[_CData], int] = {
c_byte: VT_I1,
c_ubyte: VT_UI1,
c_short: VT_I2,
c_ushort: VT_UI2,
c_long: VT_I4,
c_ulong: VT_UI4,
c_float: VT_R4,
c_double: VT_R8,
c_ulonglong: VT_UI8,
VARIANT_BOOL: VT_BOOL,
BSTR: VT_BSTR,
+ HRESULT: VT_HRESULT,
VARIANT: VT_VARIANT,
# SAFEARRAY(VARIANT *)
# By modifying the code in def _make_safearray_type(itemtype):
# Create and return a subclass of tagSAFEARRAY
from comtypes.automation import (
_ctype_to_vartype,
VT_RECORD,
VT_UNKNOWN,
IDispatch,
VT_DISPATCH,
+ VT_HRESULT,
)
meta = type(_safearray.tagSAFEARRAY) @Patch(POINTER(sa_type))
class _(object):
# Should explain the ideas how SAFEARRAY is used in comtypes
_itemtype_ = itemtype # a ctypes type
_vartype_ = vartype # a VARTYPE value: VT_...
_needsfree = False
@classmethod
def create(cls, value, extra=extra):
"""Create a POINTER(SAFEARRAY_...) instance of the correct
type; value is an object containing the items to store.
Python lists, tuples, and array.array instances containing
compatible item types can be passed to create
one-dimensional arrays. To create multidimensional arrys,
numpy arrays must be passed.
"""
+ if cls._vartype_ == VT_HRESULT:
+ raise TypeError(
+ # There are COM type libraries that define the
+ # `_midlSAFEARRAY(HRESULT)` type; however, creating `HRESULT`
+ # safearray pointer instance does not work.
+ # See also: https://github.com/enthought/comtypes/issues/668
+ "Cannot create SAFEARRAY type VT_HRESULT."
+ )
+
if comtypes.npsupport.isndarray(value):
return cls.create_from_ndarray(value, extra) Until now, it has been physically impossible to create a Additional Information: Upon further review, I found that the It is possible that Python modules are being generated based on method definitions, like in #604, where the methods are not accessible from the client side. COMMETHOD(
[dispid(8), 'hidden'],
HRESULT,
'LockConfig',
(['in'], _midlSAFEARRAY(BSTR), 'bstrIdentsToLock'),
- (['in', 'out'], POINTER(_midlSAFEARRAY(HRESULT)), 'ppsafLockResults')
),
COMMETHOD(
[dispid(9), 'hidden'],
HRESULT,
'UnlockConfig',
(['in'], _midlSAFEARRAY(BSTR), 'bstrIdentsToUnlock'),
- (['in', 'out'], POINTER(_midlSAFEARRAY(HRESULT)), 'ppsafUnlockResults')
), |
Thank you for the wonderful comtypes. I sucessfully use it to interact with a COM interface 'HeidenhainDNC.dll'
The only thing I had to modify was the '_ctype_to_vartype' dict within the 'automation.py' file:
_ctype_to_vartype: Dict[Type[_CData], int] = {
HRESULT: VT_HRESULT, # added this line for HeidenhainDNC.dll to work
How could I use the comtypes package without modifing this file?
Any hint are appreciated.
comtypes 1.4.8
python 3.13.0
The text was updated successfully, but these errors were encountered: