客户端应用程序
以下示例来自平台软件开发工具包的 RPC\Hello 目录中的“Hello World”应用程序 (SDK) 。 Helloc.c 源文件包含包含 MIDL 生成的头文件 Hello.h 的指令。 在 Hello.h 中是包含 Rpc.h 和 rpcndr.h 的指令,其中包含 RPC 运行时例程、 HelloProc 和 Shutdown 的定义,以及客户端和服务器应用程序使用的数据类型。 MIDL 编译器必须与以下示例一起使用。
由于客户端正在管理其与服务器的连接,因此客户端应用程序调用运行时函数来建立服务器的句柄,并在远程过程调用完成后释放此句柄。 函数 RpcStringBindingCompose 将绑定句柄的组件合并到该句柄的字符串表示形式中,并为字符串绑定分配内存。 函数 RpcBindingFromStringBinding 从该字符串表示形式为客户端应用程序创建hello_ClientIfHandle服务器绑定句柄。
在调用 RpcStringBindingCompose 时,参数不会指定 UUID,因为本教程假定只有一个接口“hello”实现。此外,调用未指定网络地址,因为应用程序将使用默认值,即本地主机。 协议序列是表示基础网络传输的字符串。 终结点是特定于协议序列的名称。 此示例使用命名管道进行网络传输,因此协议序列为“ncacn_np”。 终结点名称为“\pipe\hello”。
实际的远程过程调用 HelloProc 和 Shutdown 发生在 RPC 异常处理程序中,这是一组宏,可用于控制应用程序代码外部发生的异常。 如果 RPC 运行时模块报告异常,则控件将传递给 RpcExcept 块。 在此位置,可以插入代码以执行任何所需的清理,然后正常退出。 此示例程序只是通知用户发生了异常。 如果不想使用异常,可以使用 ACF 属性 comm_status 和 fault_status 来报告错误。
远程过程调用完成后,客户端首先调用 RpcStringFree 以释放为字符串绑定分配的内存。 请注意,创建绑定句柄后,客户端程序可以随时释放字符串绑定。 客户端接下来调用 RpcBindingFree 以释放句柄。
/* file: helloc.c */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "hello.h"
#include <windows.h>
void main()
{
RPC_STATUS status;
unsigned char * pszUuid = NULL;
unsigned char * pszProtocolSequence = "ncacn_np";
unsigned char * pszNetworkAddress = NULL;
unsigned char * pszEndpoint = "\\pipe\\hello";
unsigned char * pszOptions = NULL;
unsigned char * pszStringBinding = NULL;
unsigned char * pszString = "hello, world";
unsigned long ulCode;
status = RpcStringBindingCompose(pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszStringBinding);
if (status) exit(status);
status = RpcBindingFromStringBinding(pszStringBinding, &hello_ClientIfHandle);
if (status) exit(status);
RpcTryExcept
{
HelloProc(pszString);
Shutdown();
}
RpcExcept(1)
{
ulCode = RpcExceptionCode();
printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
}
RpcEndExcept
status = RpcStringFree(&pszStringBinding);
if (status) exit(status);
status = RpcBindingFree(&hello_IfHandle);
if (status) exit(status);
exit(0);
}
/******************************************************/
/* MIDL allocate and free */
/******************************************************/
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}