Windows RPC hello world
Rpc(Remote Procedure Call)远程过程调用定义创建分布式客户/服务端的强有力的开发技术。Rpc的运行的库管理大多数的网络通讯方面的细节,这就允许我们在实现时可以专注于我们的需求细节实现了。
我先来建立一个具有代表性的例子,然后在后序的的章节里写出我进一步的理解,理解有误之处,希望大家指出,共同学习、交流、进步。我的一个网友有一句话,常常影响着我,一个人不怕被人指出错误,可怕的就是到死依然不知错了。
计算机语言的大多数教程都使用着一个HellodWorld的经典例子作为初学者的入门写作,这里也来看一下类似的HelloWorld的例子是如何实现的,还是让我先给出一个单机版的例子先:
// Hello.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
void HelloWorld()
{
printf("%s"n","Hello World!");
}
int _tmain(int argc, _TCHAR* argv[])
{
HelloWorld();
return 0;
}
这样我们就完成了一个单机版的HelloWorld的程序了。功能简单,实现容易,但是富有很大的代表性。说明了程序的结构,所以也常作为入门的一个例子。
用Rpc来实现这个例子没有这第简单的了,不过也不是很复杂,下面我就把我建立这个程序的步骤写下来。供大家参考。
第一步:建立好服务器和客户端交互通讯的定义,然后客户端按照这个说明去使用定义的功能,而服务端就要按照这个约定去完成这个功能。在远程调用过程中,RPC库管理着和通讯的很多工作了,故我们可以专注我们的实现。这些文件是一种IDL文件,它和传统的C语言有着非常相仿。例子如下
[
uuid(7a98c250-6808-11cf-b73b-00aa00b677a7),//接口标识
//endpoint("ncacn_ip_tcp:[23225]"),//远端
version(1.0),//版本
//pointer_default(unique)]//处理指针的缺省为可空的指针
] //接口头部,指定了这个接口的一些属性,uuid是不可省的。
interface Hello
{
void Hello ();
}
这样就定义这个交互的标准了,再运行下面这个命令得到我们最终想要的代理,存根和标准通讯的文件。
Midl hello.idl
这样就会在同目录下生成如下的文件hello.h,hello_c.c,hello_s.c文件
第二步:建立客户端。
建立一个工程,加入hello.h hello_c.c文件。并要链入rpcrt4.lib库文件。
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "hello.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_IfHandle);
if (status)
{
exit(status);
}
RpcTryExcept
{
Hello();
}
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);
} // end main()

/******************************************************/
/* 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);
}
第三步:建立服务端。
建立一个工程,加入hello.h hello_s.c,链入rpcrt4.lib. 并要实现hello函数。
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "hello.h"
void main()
{
RPC_STATUS status;
unsigned char * pszProtocolSequence = "ncacn_np";
unsigned char * pszSecurity = NULL;
unsigned char * pszEndpoint = "\\pipe\\hello";
unsigned int cMinCalls = 1;
unsigned int cMaxCalls = 20;
unsigned int fDontWait = FALSE;
status = RpcServerUseProtseqEp(pszProtocolSequence,
cMaxCalls,
pszEndpoint,
pszSecurity);
if (status)
{
exit(status);
}
status = RpcServerRegisterIf(hello_v1_0_s_ifspec,
NULL,
NULL);
if (status)
{
exit(status);
}
status = RpcServerListen(cMinCalls,
cMaxCalls,
fDontWait);
if (status)
{
exit(status);
}
} // end main()
/******************************************************/
/* 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);
}
void Hello()
{
printf("Hello world!");
}
虽然没有单机版的简单,但这个还是相当的简单的了,几步就做出了一个分布式的hello world.这个小例子是参照MSDN上写的.


浙公网安备 33010602011771号