2013-10-08 33 views
2

我有和名为ISimpleCom的ATL简单对象接口。 该对象实现连接点。 我想知道为什么“普通”的COM方法参数必须带有前缀和属性,但事件方法没有?COM:方法参数属性总是需要的?

ISimpleCom方法:

[id(1)] HRESULT Calculate([in] VARIANT_BOOL a_bFireEvent, [out,retval] LONG* a_lTotalMarks);

_ISimpleComEvents方法(事件 “签名” 注 “a_lTotalMark” S参数是不归): [id(1)] HRESULT TotalMarks(LONG a_lTotalMarks);

Fire_TotalMarks(12); <-- will fire the event in my case to C# manage code 
+1

他们仍然应该归功于,它不清楚你如何使用向导。没有那么重要,[in]是默认的,并且始终应该是连接点,因为您不能指望实际订阅事件的客户端代码。 –

+0

'[in]'和/或'[out]'必须在那里,否则编组人员不知道在派对之间的路上如何携带价值。 –

+0

@RomanR。你会感到惊讶,但编组工作正常,没有为连接点方法参数设置任何属性。我不知道如何,但它的工作原理,即使对于更复杂的对象,如SAFEARRAY封送到托管代码(在我的情况下,C#)也可以正常工作! – JobNick

回答

0

在COM的属性向COM运行时提示它可以做出的优化。例如,如果参数被标记为[in],则运行时知道它不必为返回值分配任何内存。如果[out]它只担心内存作为返回值。 简而言之,它有助于代码更有效地运行,所以使用它们总是一个好主意(无论是连接点还是方法参数)。

它还可以防止运行时错误。例如,一个被调用的函数将一个值设置为一个没有标记为[out]的参数将不会得到它期望返回调用函数的值,因为运行时不知道将其归还。

+0

那么根据你的帖子这个属性可以忽略?顺便说一句,如果你的COM方法有LONG *作为没有[out]属性的参数,你会从C#等托管代码中调用该函数(C#会将此参数解释为'ref int')并进行分配,它将被编组回到COM。 – JobNick

+0

''[in]'允许更高效的编组。 '[out]'和'[retval]'是必要的(C#可能会假设其他语言不适合您的示例,如上所示)。 – edtheprogrammerguy

+0

如果我得到这个正确的连接点方法参数应始终归因于[in]。 – JobNick

1

参数属性魔法是explained on MSDN here

的[IN]属性具有相反的属性,[OUT],这表明 一个参数是从被调用过程返回到 调用过程。 [in]和[out]属性被称为 定向参数属性,因为它们指定传递参数的 中的方向。参数可以定义为[in], [out]或[in,out]。

[in]属性标识由 客户端存根编组以传送到服务器的参数。

当没有指定 方向参数属性时,[in]属性默认应用于参数。

这是简要如下:

  • 参数inoutin/out,无方向的参数是没有意义的,所以如果你省略了属性,[in]仍然适用;您不必输入[in],但为清晰起见,这是一个好主意
  • 这些参数定义了参数值传输的方向,当涉及到封送和传输时,当呼叫假设呼叫者/被呼叫者有一些传输时方式