这个变量参数列表函数调用如何工作?

时间:2011-08-18 07:20:33

标签: c++ c winapi visual-c++ rpc

当程序需要使用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,该{{3}}被声明为...作为第三个参数并执行实际工作。 MyInterfaceRpc__MIDL_ProcFormatString只是MIDL生成的一系列硬编码字节,因此第二个参数是该包含在与包装函数相同的.c文件中并具有静态存储持续时间的数组中的子节的开头。

参数(fileIdfilePipe)如何传递到NdrClientCall2()?我没有看到他们被通过。他们如何从包装器到NdrClientCall2()

2 个答案:

答案 0 :(得分:1)

嗯,不太确定但在MSDN doc(表示最后一个参数是指向客户端调用堆栈的指针)的行之间读取它听起来像{{ 1}}函数可以采用STUB_DESC结构,弄清楚参数类型和大小是什么,从堆栈中提取它们,执行调用远程接口的工作,然后将结果写回堆栈中的适当位置(对于OUT)参数)。

答案 1 :(得分:1)

在不深入研究的情况下,在我看来,通过在堆栈上传递第一个参数的地址(& IDL_handle),NdrClientCall2的实现可以看到也在堆栈上的后续参数。 NdrClientCall2的第二个参数表示varargs的数量和大小。