python接口调用失败_从Python脚本调用COM接口

在尝试使用Python脚本调用COM接口时遇到问题,具体表现为Python无法正确识别同时具有Set和Get定义的Property方法。尽管在ODL文件中Property方法正确地设置了propget和propput,但Python调用时将其解释为DISPATCH_PROPERTYGET,导致调用失败。更新中提到,使用GetProperty方法会导致AttributeError,而SetProperty方法可以正常工作。问题可能与Python与VBScript之间的语法差异有关。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我尝试使用Python脚本调用COM接口。在

我从ActivePython获得了Python的安装,我正在尝试使用脚本引擎编写部分代码。这通常适用于VBScript和JScript,但现在我想用PythonScript扩展它。在

脚本引擎是通过我定义的COM接口调用的。似乎大多数事情都能正常工作,但是当我调用一个同时具有Set和Get-defined的方法时,Python无法找到该方法的正确版本。在

在我的ODL文件中,我定义了一个名为Property的方法,它有一个propget和propput标志,具有相同的名称和id,如下所示:[propget,id(100)] HRESULT Property([in]BSTR* name,[out,retval]VARIANT* val);

[propput,id(100)] HRESULT Property([in]BSTR* name,[in]VARIANT val);

从JScript调用时,我可以这样做:

^{pr2}$

在COleDispatchImpl::Invoke第1309行中的脚本引擎“oledisp1.cpp”中,此调用被解释为DISPATCH_方法方法,然后根据对这部分代码中参数的测试将其更正为DISPATCH_PROPERTYPUTREF:// treat member calls on properties just like property get/set

if ((wFlags == DISPATCH_METHOD) &&

((pEntry->pfn == NULL && pEntry->pfnSet == NULL) ||

(pEntry->pfn == NULL && pEntry->pfnSet != NULL) ||

(pEntry->pfn != NULL && pEntry->pfnSet != NULL)))

{

// the entry describes a property but a method call is being

// attempted -- change it to a property get/set based on the

// number of parameters being passed.

wFlags &= ~DISPATCH_METHOD;

UINT nExpectedArgs = pEntry->lpszParams != NULL ?

(UINT)lstrlenA(pEntry->lpszParams) : 0;

if (pDispParams->cArgs <= nExpectedArgs)

{

// no extra param -- so treat as property get

wFlags |= DISPATCH_PROPERTYGET;

}

else

{

// extra params -- treat as property set

wFlags |= DISPATCH_PROPERTYPUTREF;

pDispParams->cNamedArgs = 1;

}

}

当从Python调用相同的方法时,COleDispatchImpl::Invoke最初是使用标志DISPATCH_PROPERTYGET调用的。在

这当然是错误的,因为调用必须被解释为DISPATCH_PROPERTYPUTREF,那么方法调用将失败,参数数目错误。在

为什么Python脚本会误解这个方法调用?在

Python脚本是否无法处理旧文件中定义的propget和propput方法?在

我能在Python脚本的方法调用中指出它是我要调用的方法的propput版本吗?在

更新1

上述代码调用以下宏:DISP_PROPERTY_PARAM_ID(CMyScriptingObject,"Property",100,GetProperty,SetProperty,VT_VARIANT,VTS_BSTR)

这里创建了Set和Get(在本例中为SetProperty和GetProperty)方法。我现在发现,如果我隐式调用SetProperty方法,它会起作用:Session.SetProperty("Test",2)

直觉上,我希望GetProperty可以这样工作:myProp = Session.GetProperty("Test")

但是,此调用失败,并出现以下错误:[13:32:49] Python Test

[13:32:52] Scripting

Python ActiveX Scripting Engine

Error: Traceback (most recent call last):

File "

myProp = Session.GetProperty("Test")

File "C:\Python27\lib\site-packages\win32comext\axscript\client\pyscript.py", line 105, in __getattr__

return getattr(self._scriptItem_.dispatchContainer,attr)

File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__

raise AttributeError("%s.%s" % (self._username_, attr))

AttributeError: Session.GetProperty

In line 20 At column -1 Error Code: 0

Source line: myProp = Session.GetProperty("Test")

它必须与多个参数相关。不过,也可能是因为我不了解Python与更简单的VBScript相比的语法。在

更新2

好的,现在我使用PythonWin程序在COM对象的注册tlb上加载工具comakepy实用程序。在这里我可以看到:# The method Property is actually a property, but must be used as a method to correctly pass the arguments

def Property(self, name=defaultNamedNotOptArg, val=pythoncom.Missing):

return self._ApplyTypes_(100, 2, (3, 0), ((8, 1), (16396, 10)), u'Property', None,name

, val)

# The method SetProperty is actually a property, but must be used as a method to correctly pass the arguments

def SetProperty(self, name=defaultNamedNotOptArg, val=defaultNamedNotOptArg):

return self._oleobj_.InvokeTypes(100, LCID, 4, (3, 0), ((8, 1), (12, 1)),name

, val)

所以,我想这就是为什么我需要调用SetProperty以及GetProperty不存在的原因。但是财产是存在的,但是我怎么称呼它呢?在

-氯化聚乙烯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值