远程过程调用-buttonrpc源码解析5-函数绑定

前面几节的文章里提到过“通过一定的技术手段,通知远程服务器调用某个函数来执行相应的功能”,本片文章分析服务端如何使用std::bind函数,统一函数调用形式。
温馨提示:std::bind除了绑定普通函数,还可以绑定类的成员函数,当绑定的是类的非静态成员函数时,此时std::bind至少需要传递两个参数,第一个参数为类的成员函数,需要通过&类名::成员函数的方式填入参数;第二个参数为类对象或者类对象指针(若std::bind发生在某个类的成员函数内,则传递这个类的this指针,见最后buttonrpc源码)。
1、先看一个简单的例子:

// 全局函数:只有一个int型参数
void globalFunc(int value)
{
	std::cout << __FUNCTION__ << " value = " << value << std::endl;
}

class A
{
public:
	// 类中成员函数:两个参数,但最后一个是int型参数
	void classFunc(double valueA, int valueB)
	{
		std::cout << __FUNCTION__ << " valueA = " << valueA << " valueB = " << valueB << std::endl;
	}

	// 类中静态成员函数:三个参数,但最后一个是int型参数
	static void classStaticFunc(char valueA, double valueB, int valueC)
	{
		std::cout << __FUNCTION__ << " valueA = " << valueA << " valueB = " << valueB << " valueC = " << valueC << std::endl;
	}
};

int main()
{
	std::map<std::string, std::function<void(int)>> mapData;

	A *a = new A;

	auto f1 = std::bind(globalFunc, std::placeholders::_1);
	mapData["global_func"] = f1;

	auto f2 = std::bind(&A::classFunc, a, 2.3, std::placeholders::_1);
	mapData["class_func"] = f2;

	auto f3 = std::bind(&A::classStaticFunc, 'c', 2.3, std::placeholders::_1);
	mapData["class_static_func"] = f3;

	mapData["global_func"](1);
	mapData["class_func"](2);
	mapData["class_static_func"](3);
	
	system("pause");
	return 0;
}

在这里插入图片描述
可以看到,型如上面的3个函数,故意设定了最后一个参数类型为int。这样,不管是全局函数还是类的成员函数,都可以通过std::bind的方式,提前绑定已知参数,得到std::function<void(int)>类型的函数对象,这样便可以统一存储在std::map<std::string, std::function<void(int)>>类型的容器中。

2、buttonrpc源码中的例子:

template<typename F>
inline void buttonrpc::bind( std::string name, F func )
{
	m_handlers[name] = std::bind(&buttonrpc::callproxy<F>, this, func, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}

template<typename F, typename S>
inline void buttonrpc::bind(std::string name, F func, S* s)
{
	m_handlers[name] = std::bind(&buttonrpc::callproxy<F, S>, this, func, s, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}

上面的buttonrpc::bind( std::string name, F func )函数内,绑定成员函数buttonrpc::callproxy<F>,并将成员this传递进入,完成这2个必要参数后,将已知函数func传入,完成早期绑定;将后面的三个占位符作为晚期绑定。
同理,buttonrpc::bind(std::string name, F func, S* s)函数内,绑定成员函数buttonrpc::callproxy<F, S>,并将成员this传递进入,完成这2个必要参数后,将已知函数func和s传入,完成早期绑定;将后面的三个占位符作为晚期绑定。

int main()
{
	buttonrpc server;
	server.as_server(5555);

	server.bind("foo_1", foo_1);
	server.bind("foo_2", foo_2);
	server.bind("foo_3", std::function<int(int)>(foo_3));
	server.bind("foo_4", foo_4);
	server.bind("foo_5", foo_5);

	ClassMem s;
	server.bind("foo_6", &ClassMem::bar, &s);

	std::cout << "run rpc server on: " << 5555 << std::endl;
	server.run();

	return 0;
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生卍流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值