我不太确定[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 == 20
,val2
为"Xello"
,并且val3->get_value()
获得50
。
我的问题是:这是否有保证的行为,即如果我使用进程外服务器或DCOM到另一台计算机,它是否会在val1
,val2
中看到相同的更改, val3
?
我以前认为[in]
向底层RPC指出参数只需要在一个方向上编组;它不必尝试将更改发送回调用方。但现在我不太确定。
我打算我的对象是自动化兼容的(即可以从VB6,Java等中使用 - 不需要自定义编组),并且它应该能够通过DCOM而不是在进程中使用,而不需要任何更改客户端代码中需要。
答案 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
将