我正在为一个应用程序实现 COM 自动化(双接口(interface))。将从 VBScript 调用自动化接口(interface)。我不太清楚该方法的参数允许哪些类型。我知道基本上值必须适合 VARIANT
,但这是否意味着 int
类型的每个参数都必须通过 VARIANT
传递,或者可以直接传递 int
吗?
例如,我的 MIDL 文件中有两种方法:
HRESULT SetDate([in] int Year, [in] int Month, [in] int Day);
HRESULT GetDate([out] int* pYear, [out] int* pMonth, [out] int* pDay);
从 VBScript 调用 SetDate
有效。调用 GetDate
失败,也就是说,在 C++ 的实现中,ITypeInfo::Invoke
返回一个指示类型错误的代码。
我发现如果我使用 VARIANT
而不是 int
,如下所示,它会起作用。
HRESULT GetDate([out] VARIANT* pYear, [out] VARIANT* pMonth, [out] VARIANT* pDay);
那么 int
是不允许参数(因为双接口(interface)),还是我必须做其他错误的事情?如果不允许 int
,为什么 SetDate
起作用 - in
和 out
参数之间有区别吗尊重?
此外,这对方法有效,尽管它们都使用 int
:
[propget] HRESULT System([out, retval] int* pSystem);
[propput] HRESULT System([in] int System);
为什么 - 属性允许的参数类型的规则不同,或者当参数声明为 retval
时?
我不太明白这一切 - 如果有人能澄清这一点,我将不胜感激。
最佳答案
显然,当您通过IDispatch
调用接口(interface)时,所有参数总是作为VARIANT
传递。然而,您的实现可能会使用其他类型。如何弥合差距?
ATL(假设这就是您正在使用的)将为您实现 Invoke
,使用将参数从 VARIANT
转换为您的方法签名使用的正确类型的代码在将调用转发给实际方法之前。
规则如下:
[in]
参数几乎可以是适合VARIANT
的任何类型,如您所见。 ATL(或您正在使用的任何库)将为您负责翻译参数。[in, out]
参数必须是VARIANT*
。如果您使用其他任何东西,调用将不起作用或返回值将丢失(我不记得它是哪种方式;您表示您在这种情况下遇到了运行时错误)。在您的方法返回时,ATL 会将参数转换为适当的VARIANT
,以便 VBScript(或任何IDispatch
客户端发出调用)可以获得输出值。[retval, out]
是一个特例。您可以使用指向您选择的任何类型的指针,ATL 会处理它。我认为使这成为可能的是返回值是在DISPPARAMS
机制之外提供的。[out]
...只是不要。它们不起作用 - VBScript 无法正确使用[out]
参数。请注意,它们将“起作用”,因为该方法将无错误地执行,但 VBScript 无法区分[out]
和[in, out]
,这意味着 VBScript期望您的方法在收到参数时释放参数上的任何值。如果您使用[out]
,则无论客户端代码在进行方法调用之前放置在参数上,都将永久泄露。
关于com - COM 自动化接口(interface)中允许的 "out"参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16512262/