是时候要写写点东西

     时间流逝,一转眼已经毕业5年了,感觉也错过了不少时光,也未能给生活流下点点滴滴。我是一个打杂程序员,工作几年,接触的东西多而杂,感觉自己已经没有一个方向,现在开始坚持写些东西,以回顾所学的东西,也给新的东西留下一点记录。接下来先从windows端的一些开发记录下。

    昨天突然想了解一下win32的RPC实现,所以在网上找了找资料,就搞了起来,利用rpc,可以使不同进程之前调用。先是服务端,新建vs2015工程,然后新建IDL(Interface description language)文件,如下 RPCDvrServer.idl

import "oaidl.idl";
import "ocidl.idl";

[
	uuid(50272674-4DEB-42D4-A37D-BE311DD06E2A),   // 唯一的UUID,用 GUIDGen 生成
	version(1.0)
]

interface RPCDvrServer
{
	error_status_t GetServerName([out, size_is(len)]char *pszName,[in]long len);

	error_status_t Add([in] long num1, [in] long num2, [out] long*res);

	error_status_t ShutDown();

}
然后再新建一个acf文件RPCDvrServer.acf

[
    implicit_handle (handle_t RPCDvrServer_IfHandle)
]

interface RPCDvrServer
{
}


编译idl文件会生成3个文件 IDvrServer_h.h ,IDvrServer_c.c, IDvrServer_s.c,其中IDvrServer_h.h和IDvrServer_s.c是服务端用,而IDvrServer_h.h和IDvrServer_c.c是客户端所用。

定义好接口后,现在来开始编写服务端,RpcServer.cpp

// RpcServer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "IDvrServer_h.h"
#define _CRT_SECURE_NO_WARNINGS  1

#pragma comment( lib, "Rpcrt4.lib" )
void StopDvrService();
long StartDvrService();

error_status_t GetServerName(
	/* [size_is][out] */ unsigned char *pszName,
	/* [in] */ long len)
{
	strncpy((char*)pszName, "RPCDvrServer", len);
	pszName[len - 1] = '\0';
	printf("服务已经启动!\n");
	return 0;
}

error_status_t Add(
	/* [in] */ long num1,
	/* [in] */ long num2,
	/* [out] */ long *rtn)
{
	*rtn = num1 + num2;
	printf("sum is:%ld\n", *rtn);
	return 0;
}

error_status_t ShutDown(void)
{
	StopDvrService();
	printf("服务已经关闭!\n");
	return 0;
}

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);
}

long StartDvrService()
{
	//RPC技术发送Local请求时使用ncalrpc协议,发送Remote请求时使用ncacn_ip_tcp或者ncacn_np协议,前者微软更推荐
	RPC_STATUS rpcStats = RpcServerUseProtseqEpW(reinterpret_cast<RPC_WSTR>(L"ncalrpc"),
		RPC_C_LISTEN_MAX_CALLS_DEFAULT,
		reinterpret_cast<RPC_WSTR>(L"msmpq_dvr"),
		NULL);
	if (rpcStats)
		exit(rpcStats);

	rpcStats = RpcServerRegisterIf(RPCDvrServer_v1_0_s_ifspec, NULL, NULL);
	if (rpcStats)
		exit(rpcStats);

	unsigned int fDontWait = false;
	rpcStats = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, fDontWait);
	if (rpcStats)
		exit(rpcStats);

	return 0;
}

void StopDvrService()
{
	RPC_STATUS rpcStatus;
	rpcStatus = RpcMgmtStopServerListening(NULL);
	rpcStatus = RpcServerUnregisterIf(NULL, NULL, FALSE);
}




int main()
{
	StartDvrService();
    return 0;
}


然后新建vs2015工程客户端

引入IDvrServer_h.h和IDvrServer_c.c,新建测试代码RpcClient.cpp

// RcpClient.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <rpc.h>
#include <tchar.h>
#include <stdio.h>
#include"IDvrServer_h.h"
#pragma comment( lib, "Rpcrt4.lib" )

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);
}

int main()
{
	RPC_WSTR pszStringBinding = NULL;
	RPC_STATUS rpcStatus = RpcStringBindingComposeW(NULL,
		reinterpret_cast<RPC_WSTR>(L"ncalrpc"),
		NULL,
		reinterpret_cast<RPC_WSTR>(L"msmpq_dvr"),
		NULL,
		&pszStringBinding);
	if (rpcStatus)
		exit(rpcStatus);

	rpcStatus = RpcBindingFromStringBinding(pszStringBinding,
		&RPCDvrServer_IfHandle);
	if (rpcStatus)
		exit(rpcStatus);
	unsigned char name[100];
	RpcTryExcept
	{
		GetServerName(name, 100);
	}
		RpcExcept(1)
	{
		unsigned long ulCode = RpcExceptionCode();
		printf("抛出异常0x%lx = %ld。\n", ulCode, ulCode);
	}
	RpcEndExcept
	
	long i = 0;
	long sum = 0;
	while (true) {
		Sleep(1000);
		i++;
		RpcTryExcept
		{	
			Add(i,i + 1,&sum);
			printf("sum is:%ld\n", sum);
		}
			RpcExcept(1)
		{
			unsigned long ulCode = RpcExceptionCode();
			printf("抛出异常0x%lx = %ld。\n", ulCode, ulCode);
		}
		RpcEndExcept
	}

    return 0;
}


致此可以跑通调用 ,后续 会研究如何回调、异步,等 等 ,也许也不会再研究,看心情,哈哈


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值