You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:47:34