【问题标题】:COM: method parameter attribute always needed?COM:总是需要方法参数属性?
【发布时间】:2013-10-15 20:09:54
【问题描述】:

我有一个名为 ISimpleCom 的 ATL 简单对象接口。 该对象实现连接点。 我想知道为什么“普通” COM 方法参数必须以 and 属性为前缀,而事件方法则不需要?

ISimpleCom 方法:

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

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

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

【问题讨论】:

  • 他们仍然应该被归因,不清楚你是如何使用向导的。不是那么重要,[in] 是默认值,并且始终应该用于连接点,因为您不能指望客户端代码实际订阅事件。
  • [in] 和/或 [out] 必须在那里,否则编组不知道通过哪种方式在各方之间传递价值。
  • @RomanR。您会感到惊讶,但在没有为连接点方法参数设置任何属性的情况下,封送处理工作正常。我不知道它是如何工作的,即使对于更“复杂”的对象,例如 SAFEARRAY 编组到托管代码(在我的情况下是 C#)也可以正常工作!
  • @HansPassant。我按照教程使用向导创建连接点方法。根据那个教程,他们没有勾选任何方法参数属性(int/out/retval),只是选择了类型并输入了一个名称。这就是“TotalMarks”“a_lTotalMarks”最终没有任何属性的方式。但正如上面提到的,它工作得很好。这就是为什么我很好奇它为什么工作......

标签: c++ visual-c++ com atl


【解决方案1】:

参数属性magic是explained on MSDN here

[in] 属性有一个相反的属性,[out],它表示 一个参数将从被调用的过程返回到 调用程序。 [in] 和 [out] 属性称为 方向参数属性,因为它们指定方向 传递了哪些参数。一个参数可以定义为[in], [out] 或 [in, out]。

[in] 属性标识由 用于传输到服务器的客户端存根。

默认情况下,[in] 属性应用于参数 指定了方向参数属性。

简述如下:

  • 参数为inoutin/out,无方向性参数没有意义,所以如果省略属性,[in]仍然适用;您不必输入[in],但为了清楚起见,这样做是个好主意
  • 这些参数定义了参数值传输的方向,当涉及到编组和传输时,调用假定在调用者/被调用者的方式上进行了一些传输

【讨论】:

    【解决方案2】:

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

    它还可以防止运行时错误。例如,被调用函数将值设置为未标记为 [out] 的参数,将无法将预期的值返回给调用函数,因为运行时不知道将其封送回。

    【讨论】:

    • 所以根据你的帖子,这个属性可以忽略吗?顺便说一句,如果您的 COM 端方法将 LONG* 作为没有 [out] 属性的参数,并且您将从托管代码(例如 C#)调用该函数(C# 将此参数解释为 ref int)并进行分配,它将被封送回到 COM。
    • [in] 允许更有效的编组。 [out][retval] 是必要的(C# 可能会假设其他语言不适合您的示例,上面)。
    • 如果我得到这个正确的连接点方法参数应该总是用 [in] 属性。
    • 推荐并且是一致的编程方式。
    猜你喜欢
    • 2018-01-01
    • 2013-06-07
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    相关资源
    最近更新 更多