可以使用[in]参数来返回数据吗?

时间:2014-07-02 04:13:54

标签: com

我不太确定[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()获得50

我的问题是:这是否有保证的行为,即如果我使用进程外服务器或DCOM到另一台计算机,它是否会在val1val2中看到相同的更改, val3

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

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

2 个答案:

答案 0 :(得分:2)

您不应该更改[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作为一个很好的起点。

答案 1 :(得分:0)

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

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