【问题标题】:Can [in] parameters be used for returning data?[in] 参数可以用于返回数据吗?
【发布时间】:2014-07-03 05:53:07
【问题描述】:

我不太确定[in][out] 如何与按值传递和按引用传递概念进行交互。 MSDN 文档明确指出[in] 表示数据从调用者流向被调用者,而[out] 是数据从被调用者流向调用者所必需的。

但是有人建议我对调用者可以检索结果的对象使用[in] 参数。

IDL 中的示例方法定义:

HRESULT _stdcall a_method( [in] long *arg1, [in] BSTR arg2, [in] IAnObject *arg3 );

在我的服务器实现这个方法(使用C++),我可以这样写:

*arg1 = 20;
arg2[0] = L'X';    // after checking length of string is not 0
arg3->set_value(50);

在客户端代码中,使用 C++:

long val1 = 10;
BSTR val2 = SysAllocString(L"hello");
IAnObject *val3 = AnObject_Factory::Create();  

ptr->a_method(&val1, val2, val3);

当我尝试这个(通过进程内服务器使用我的对象)时,来自服务器的所有三个更改都传播到客户端,即val1 == 20val2"Xello",而val3->get_value() 得到了@ 987654333@.

我的问题是:这是保证行为,即如果我使用进程外服务器或 DCOM 到另一台机器,它会在 val1val2val3 中看到相同的变化吗?

我之前认为[in] 向底层 RPC 表明该参数只需要在一个方向上编组;它不必尝试将更改发送回调用者。但现在我不太确定了。

我打算让我的对象与自动化兼容(即可从 VB6、Java 等使用 - 无需自定义编组),并且它应该能够通过 DCOM 而不是进程内使用,无需任何更改需要在客户端代码中。

【问题讨论】:

    标签: com


    【解决方案1】:

    你不应该改变[in]参数的内容,所以下面的代码是错误的:

    *arg1 = 20;
    arg2[0] = L'X';    // after checking length of string is not 0
    

    您看到这些更改正在反映出来,因为您是在同一个公寓内拨打电话,而没有发生编组。返回值的正确方法是使用 [out][in, out] 参数。

    但是,你可以访问它的内容并调用它的方法(用于接口指针),所以下面的代码是正确的:

    arg3->set_value(50);
    

    编辑:进一步回答您的问题。

    编组可以两种方式发生,[in][out] 属性说明方式。

    对于自动化,我建议您返回的参数不要超过典型的 [out, retval] 参数,以支持脚本语言。如果必须返回多个值,请返回带有属性的 IDispatch。如果您认真对待可编写脚本的自动化,请查看 this blog post 作为一个很好的起点。

    【讨论】:

      【解决方案2】:

      为了扩展@Paulo-madeira 的回答,我可以保证,如果涉及代理,那

      *arg1 = 20;
      arg2[0] = L'X';    // after checking length of string is not 0
      

      at best 被忽略,最坏的情况下会破坏堆。

      【讨论】:

        猜你喜欢
        • 2011-11-17
        • 2020-05-23
        • 2011-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多