如何将Python值列表转换为兼容COM SAFEARRAY格式的形式?
Python调用COM接口SetValues时SAFEARRAY参数报错
我有点惊讶之前居然没人探讨过这个问题。
该方法的C语言调用方式如下:
SetValues(BSTR Keyword, SAFEARRAY * Data)
我尝试了以下Python代码:
handle = win32com.client.Dispatch("My.Application") vals = (1.1, 2.2, 3.3) safe_vals = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, vals) handle.SetValues("PUT_IT_HERE", safe_vals)
这引发了如下错误:
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.
如果直接传入vals:
res = handle.SetValues("PUT_IT_HERE", vals)
得到错误:
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147220988), None)
我认为需要某种转换才能让其兼容SAFEARRAY *,但相关说明一直不够清晰。
解决方案
方法1:将一维序列包装为嵌套序列
win32com构造SAFEARRAY时,一维数组需要传入嵌套形式的序列(比如列表的列表),修改代码如下:
import win32com.client import pythoncom handle = win32com.client.Dispatch("My.Application") vals = [1.1, 2.2, 3.3] # 包装为嵌套列表,匹配一维SAFEARRAY要求 safe_vals = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, [vals]) handle.SetValues("PUT_IT_HERE", safe_vals)
方法2:使用MakePy自动生成包装类
运行一次EnsureDispatch生成对应COM对象的Python包装类,后续调用时会自动处理参数转换:
# 首次运行生成包装类,之后可注释 win32com.client.gencache.EnsureDispatch("My.Application") handle = win32com.client.Dispatch("My.Application") vals = [1.1, 2.2, 3.3] handle.SetValues("PUT_IT_HERE", vals)
方法3:手动创建SAFEARRAY
使用pythoncom.SafeArrayCreateVector直接构造符合要求的SAFEARRAY对象:
import pythoncom import win32com.client handle = win32com.client.Dispatch("My.Application") vals = [1.1, 2.2, 3.3] # 创建一维双精度类型的SAFEARRAY sa = pythoncom.SafeArrayCreateVector(pythoncom.VT_R8, 0, len(vals)) for idx, val in enumerate(vals): sa.PutElement(idx, val) handle.SetValues("PUT_IT_HERE", sa)
内容的提问来源于stack exchange,提问作者Jiminion
相关产品推荐
相关产品推荐

