Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这个变量参数列表函数调用是如何工作的?_C++_C_Winapi_Visual C++_Rpc - Fatal编程技术网

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

C++ 这个变量参数列表函数调用是如何工作的?,c++,c,winapi,visual-c++,rpc,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] */ handl

当程序需要使用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;
}
在这里,调用被转发到声明有
作为第三个参数并执行实际作业的节点
MyInterfaceRpc\uuuMidl\uProcFormatString
只是由MIDL生成的硬编码字节序列,因此第二个参数是该数组中一个子段的开始,该子段在包装函数所在的.c文件中声明,并具有静态存储持续时间


参数(
fileId
filePipe
)如何传递到
NdrClientCall2()
?我看他们没有通过。它们是如何从包装器到
NdrClientCall2()
的?

嗯,不太确定,但在中的行之间读取(表示最后一个参数是指向客户端调用堆栈的指针),听起来
NdrClientCall2
函数可以采用存根描述结构,找出参数的类型和大小,从堆栈中提取它们,调用远程接口,然后将结果写回堆栈上的正确位置(out参数)。

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