这个可变参数列表函数调用是如何工作的?
Posted
技术标签:
【中文标题】这个可变参数列表函数调用是如何工作的?【英文标题】:How does this variable parameters list function call works? 【发布时间】:2011-08-18 07:20:33 【问题描述】:当程序需要使用 Microsoft RPC 进行通信时,开发人员通常会为所有方法编写 IDL 定义,例如:
error_status_t rpcMyInterfaceGetFile( [in] const GUID fileId, [out] BYTE_PIPE filePipe );
由 MIDL 编译器编译并产生一个包装函数:
/* [fault_status][comm_status] */ error_status_t rpcMyInterfacerGetFile(
/* [in] */ handle_t IDL_handle,
/* [in] */ const GUID fileId,
/* [out] */ BYTE_PIPE filePipe)
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall2(
( PMIDL_STUB_DESC )&IMyInterfaceRpc_StubDesc,
(PFORMAT_STRING) &MyInterfaceRpc__MIDL_ProcFormatString.Format[SomeNumberHere],
( unsigned char * )&IDL_handle);
return ( error_status_t )_RetVal.Simple;
这里调用被转发到NdrClientCall2()
RPC runtime function,它被声明为将...
作为第三个参数并执行实际工作。 MyInterfaceRpc__MIDL_ProcFormatString
只是 MIDL 生成的硬编码字节序列,因此第二个参数是该数组中的一个小节的开头,该数组在与包装函数相同的 .c 文件中声明并具有静态存储持续时间。
参数(fileId
和filePipe
)如何传递到NdrClientCall2()
?我没有看到他们被通过。它们是如何从包装器中获取到NdrClientCall2()
的?
【问题讨论】:
【参考方案1】:嗯,不太确定,但在 MSDN doc 的行之间读取(这表示最后一个参数是 指向客户端调用堆栈的指针)听起来像 NdrClientCall2
函数可以采用 STUB_DESC 结构,找出参数类型和大小,从堆栈中提取它们,完成调用远程接口的工作,然后将结果写回堆栈上的正确位置(用于 OUT 参数)。
【讨论】:
【参考方案2】:无需深入研究,在我看来,通过传递堆栈上第一个参数的地址(&IDL_handle),NdrClientCall2 的实现可以看到也在堆栈上的后续参数。 NdrClientCall2 的第二个参数表示可变参数的数量和大小。
【讨论】:
以上是关于这个可变参数列表函数调用是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章