当程序需要使用 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()
的?
最佳答案
嗯,不太确定,但请阅读 MSDN doc 中的字里行间(这表明最后一个参数是指向客户端调用堆栈的指针)这听起来像 NdrClientCall2
函数可以采用 STUB_DESC 结构,找出参数类型和大小是,从堆栈中提取它们,执行调用远程接口(interface)的工作,然后将结果写回到堆栈上的正确位置(用于 OUT 参数)。
关于c++ - 这个可变参数列表函数调用是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7103752/