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

Python向COM组件方法传递字符串引用时类型不兼容问题

OCX控件EcrCmd方法调用参数类型不兼容问题

方法定义(VS C#)

该OCX中的EcrCmd方法在C#中的定义如下:

[DispId(17)]
[MethodImpl(MethodImplOptions.PreserveSig | MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int EcrCmd([MarshalAs(UnmanagedType.BStr)] string Command, [MarshalAs(UnmanagedType.BStr)] ref string pResult);

可以看到第二个参数pResult是引用传递的BStr类型字符串。

我的Python代码

self.frame = wx.Frame(parent=None, id=wx.ID_ANY,size=(500,500), title='Python Interface to COECRCOM')
self.gd = wx.lib.activex.ActiveXCtrl(self.frame, "COECRCOM.CoEcrComCtrl.1")
status = self.gd.ctrl.Status
print(status)

error = ""
cmd = self.gd.ctrl.EcrCmd("nofis apri", error)
print(cmd)
print(error)

访问self.gd.ctrl.Status正常,但调用EcrCmd时触发类型不兼容错误。

报错信息

Traceback (most recent call last):
  File "...lib\site-packages\comtypes\automation.py", line 855, in Invoke
    byref(result), byref(excepinfo), byref(argerr))
_ctypes.COMError: (-2147352571, 'Type incompatibility.', (None, None, None, 0, None))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File main.py", line 31, in <module>
    app = MainApp()
  File "main.py", line 20, in __init__
    cmd = self.gd.ctrl.EcrCmd("nofis apri", error)
  File "...lib\site-packages\comtypes\_memberspec.py", line 448, in func
    return obj.Invoke(memid, _invkind=1, *args, **kw) # DISPATCH_METHOD
  File "...lib\site-packages\comtypes\automation.py", line 878, in Invoke
    args))
_ctypes.COMError: (-2147352571, 'Type incompatibility.', ('TypeError: Parameter 1', ('nofis apri', '')))

环境信息

  • 系统:32位Windows
  • Python版本:3.7.13
  • comtypes版本:v1.2.1
  • wxPython版本:4.0.4

解决方案

问题出在第二个参数的传递方式:C#中的ref string要求传递可修改的引用类型,而Python原生字符串是不可变类型,无法满足COM组件的参数要求。需要改用comtypes提供的BSTR类型并通过引用传递:

  1. 导入comtypes相关类型:
import comtypes
from comtypes.automation import BSTR
  1. 修改调用代码:
# 初始化BSTR对象
error = BSTR("")
# 传递BSTR的引用给方法
cmd = self.gd.ctrl.EcrCmd("nofis apri", comtypes.byref(error))
print(cmd)
# 通过value属性获取返回的字符串结果
print(error.value)

也可以使用ctypes的c_wchar_p类型实现(但BSTR更适配COM字符串标准):

import ctypes
error = ctypes.c_wchar_p("")
cmd = self.gd.ctrl.EcrCmd("nofis apri", ctypes.byref(error))
print(cmd)
print(error.value)

核心逻辑是:COM组件需要能修改传入的字符串参数,必须用COM兼容的可变字符串类型并以引用方式传递,才能匹配ref string的参数要求。

内容的提问来源于stack exchange,提问作者Antonino Bonanno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:10:09