我尝试使用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不存在的原因。但是财产是存在的,但是我怎么称呼它呢?在
-氯化聚乙烯