User-Defined Data Types in Messages(用户自定义类型)
All user-defined types must be explicitly “announced” so that CAF can (de)serialize them correctly.

之前干活,一开始不知道CAF自带序列化,都用boost库来做序列化,就是变string 类型发送,发现很多STL有些搞搞比较麻烦,发现诶?CAF居然比boost库好使!

那么就来搞一下看看.

先看一个例子(也是usermanual 里唯一的一个例子,呵呵呵~)其他的例子在github官网里https://github.com/actor-framework/actor-framework/tree/master/examples/type_system (就五个收益很大)

没看错就是那么简单的使用,announce函数。第一个参数是一个string那么之后就是他的所有成员。怎么实现我也不是很懂,上图

大致就是TS 就是参数的类型,可以是可变长度,然后检查他们的类型,我第一看到Is_pod 查了一下(pod类型 是plain old data)就是完全兼容C语言的编程的。(涨姿势了~)

还有uniform_type_info是CAF自己的一个关于类型什么的(没深究,只知道与RTTI有关)。还有一个重要的地方就是你必须写明你要发送的结构体的比较函数 ==(下面代码上有)

进入正题。(announce1.cpp)代码有一点点小长但是信息量很大。

  1. // POD struct
  2. struct foo {
  3. std::vector<int> a;
  4. int b;
  5. };
  6.  
  7. // announce requires foo to have the equal operator implemented
  8. bool operator==(const foo& lhs, const foo& rhs) {
  9. return lhs.a == rhs.a && lhs.b == rhs.b;
  10. }
  11.  
  12. // a pair of two ints
  13. using foo_pair = std::pair<int, int>;
  14.  
  15. // another pair of two ints
  16. using foo_pair2 = std::pair<int, int>;
  17.  
  18. // a struct with member vector<vector<...>>
  19. struct foo2 {
  20. int a;
  21. vector<vector<double>> b;
  22. };
  23.  
  24. bool operator==(const foo2& lhs, const foo2& rhs) {
  25. return lhs.a == rhs.a && lhs.b == rhs.b;
  26. }
  27.  
  28. // receives `remaining` messages
  29. void testee(event_based_actor* self, size_t remaining) {
  30. auto set_next_behavior = [=] {
  31. if (remaining > ) testee(self, remaining - );
  32. else self->quit();
  33. };
  34. self->become (
  35. // note: we sent a foo_pair2, but match on foo_pair
  36. // that's safe because both are aliases for std::pair<int, int>
  37. [=](const foo_pair& val) {
  38. cout << "foo_pair("
  39. << val.first << ", "
  40. << val.second << ")"
  41. << endl;
  42. set_next_behavior();
  43. },
  44. [=](const foo& val) {
  45. cout << "foo({";
  46. auto i = val.a.begin();
  47. auto end = val.a.end();
  48. if (i != end) {
  49. cout << *i;
  50. while (++i != end) {
  51. cout << ", " << *i;
  52. }
  53. }
  54. cout << "}, " << val.b << ")" << endl;
  55. set_next_behavior();
  56. }
  57. );
  58. }
  59.  
  60. int main(int, char**) {
  61. // announces foo to the libcaf type system;
  62. // the function expects member pointers to all elements of foo
  63. announce<foo>("foo", &foo::a, &foo::b);
  64. // announce foo2 to the libcaf type system,
  65. // note that recursive containers are managed automatically by libcaf
  66. announce<foo2>("foo2", &foo2::a, &foo2::b);
  67. // serialization can throw if types are not announced properly
  68. try {
  69. // init some test data
  70. foo2 vd;
  71. vd.a = ;
  72. vd.b.resize();
  73. vd.b.back().push_back();
  74. // serialize test data
  75. vector<char> buf;
  76. binary_serializer bs(std::back_inserter(buf));
  77. bs << vd;
  78. // deserialize written test data from buffer
  79. binary_deserializer bd(buf.data(), buf.size());
  80. foo2 vd2;
  81. uniform_typeid<foo2>()->deserialize(&vd2, &bd);
  82. // deserialized data must be equal to original input
  83. assert(vd == vd2);
  84. // announce std::pair<int, int> to the type system
  85. announce<foo_pair>("foo_pair", &foo_pair::first, &foo_pair::second);
  86. // libcaf returns the same uniform_type_info
  87. // instance for the type aliases foo_pair and foo_pair2
  88. assert(uniform_typeid<foo_pair>() == uniform_typeid<foo_pair2>());
  89. }
  90. catch (std::exception& e) {
  91. cerr << "error during type (de)serialization: " << e.what() << endl;
  92. return -;
  93. }
  94. // spawn a testee that receives two messages of user-defined type
  95. auto t = spawn(testee, size_t{});
  96. { // lifetime scope of self
  97. scoped_actor self;
  98. // send t a foo
  99. self->send(t, foo{std::vector<int>{, , , }, });
  100. // send t a foo_pair2
  101. self->send(t, foo_pair2{, });
  102. }
  103. await_all_actors_done();
  104. shutdown();
  105. }

一开始看,就是声明了两种结构体。foo 和foo2,foo2里面有vector<vector<double>> b(其实这里就告诉我们,它不但支持STL,还支持嵌套,而且我亲测pair,map都是可以的。其他应该也没问题吧。)

然后testee里定义了接受两种类型的消息一种是<int,int>(不管别名),一种是结构体foo 是的没看错,都不用序列化了,直接传(// note that recursive containers are managed automatically by libcaf)。

真心方便,然后是main函数里,使用了二进制去序列化类,再使用反序列化,整个过程就像用读文件非常的方便(注意捕获异常)。那么在最后的scoped_actor send也直接把类传过去非常的方便。

为了证明好用,支持remote actor我写了一个很难看的代码。

  1. #include <vector>
  2. #include <iostream>
  3. #include "caf/all.hpp"
  4. #include "caf/io/all.hpp"
  5. using std::cout;
  6. using std::endl;
  7. using std::vector;
  8. using std::map;
  9. using std::pair;
  10. using namespace caf;
  11.  
  12. struct foo {
  13. std::vector<vector<map<int,pair<int,int>>>> a;
  14. int b;
  15. };
  16. bool operator==(const foo& lhs, const foo& rhs) {
  17. return lhs.a == rhs.a && lhs.b == rhs.b;
  18. }
  19. // receives `remaining` messages
  20. void testee(event_based_actor* self) {
  21. self->become (
  22. [=](const foo& val) {
  23. aout(self)<<"get it"<<endl;
  24. }
  25. );
  26. }
  27. int main(int, char**) {
  28. // announce<foo2>("foo2", &foo2::a, &foo2::b);
  29. announce<foo>("foo", &foo::a, &foo::b);
  30. auto actor = spawn(testee);
  31. caf::io::publish(actor,);
  32. { // lifetime scope of self
  33. scoped_actor self;
  34. auto remoter = caf::io::remote_actor("localhost", );
  35. self->send(remoter, foo{std::vector<vector<map<int,pair<int,int>>>>{},,});
  36. }
  37. await_all_actors_done();
  38. shutdown();
  39. }

结果为

不得不服还是很方便的!

码字不容易,求粉丝~互粉呀~

CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)的更多相关文章

  1. c、c++ 结构体的嵌套

    c.c++ 结构体的嵌套 /************************************************************************/ /* 嵌套结构体 * C ...

  2. (60) 结构体指针、结构体变量嵌套、结构体指针嵌套、函数指针、数组指针、指针数组、typedef 综合运用

    #include<stdio.h> #include<iostream> #include<malloc.h> /* author : 吴永聪 program: 结 ...

  3. C++结构体与Delphi结构体相互传参,结构体中包含结构体的嵌套,数组指针

    //结构体的声明 typedef struct Mwinddirectbaseline { char* p; int s; int i; }Mwinddirectbaseline; typedef s ...

  4. C语言 结构体(嵌套结构体--结构体数组)

    //结构体--嵌套结构体和结构体数组 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> ...

  5. golang中结构体的嵌套、方法的继承、方法的重写

    package main import "fmt" type human struct { name, phone string age int8 } type student s ...

  6. Go语言基础之结构体

    Go语言基础之结构体 Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念.Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性. 类型别名和自定义类型 自定义类型 在G ...

  7. Go语言 - 结构体 | 方法

    自定义类型和类型别名 自定义类型 在Go语言中有一些基本的数据类型,如string.整型.浮点型.布尔等数据类型, Go语言中可以使用type关键字来定义自定义类型. 自定义类型是定义了一个全新的类型 ...

  8. Go part 5 结构体,方法与接收器

    结构体 结构体定义 结构体的定义只是一种内存布局的描述(相当于是一个模板),只有当结构体实例化时,才会真正分配内存空间 结构体是一种复合的基本类型,通过关键字 type 定义为 自定义 类型后,使结构 ...

  9. Golang的面向对象编程【结构体、方法、继承、接口】

    Golang也支持面向对象编程.但与以前学过传统的面向对象编程语言有区别.1)Golang没有类class,Go语言的结构体struct和类class有相似的特性.2)Golang中不存在继承,方法重 ...

随机推荐

  1. URAL 1777 D - Anindilyakwa 暴力

    D - AnindilyakwaTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/v ...

  2. delphi SpeedButtonDown

    的属性 的事件 的方法   设置SpeedButton的Down的属性      AllowAllUp属性 当有多个SpeedButton时 让有2个按钮都能处于按下状态 设置它的GroupIndex ...

  3. android UI进阶之实现listview中checkbox的多选与记录

    今天继续和大家分享涉及到listview的内容.在很多时候,我们会用到listview和checkbox配合来提供给用户一些选择操作.比如在一个 清单页面,我们需要记录用户勾选了哪些条目.这个的实现并 ...

  4. mydumper原理2

    使用mydumper备份发生Waiting for table flush,导致所有线程都无法读和写 版本 mydumper 0.9.1OS centos6.6 X86_64mysql 5.6.25- ...

  5. OpenVPN莫名其妙断线的问题及其解决-confirm

    本文很短,目的在于confirm一下凌乱的< OpenVPN莫名其妙断线的问题及其解决>,如果看觉得我比较啰嗦,那么一定要看看最后一个小节,好在CSDN为每篇文章都自动添加了目录,可以直接 ...

  6. [置顶] mybatis的批量新增

    开发项目中,总是与数据打交道,有的时候将数据放入到一个集合中,然后在遍历集合一条一条的插入,感觉效率超不好,最近又碰到这个问题,插入50条数据用了将近1s,完全满足不了系统的需求.效率必须加快,然后网 ...

  7. php对象当参数传递 && php深复制和浅复制

    把对象当参数传递给方法,在方法里改过对象后,影响到外面的对象  因为对象是引用传递过去的 class Book { public $name; public function __construct( ...

  8. python之装饰器详解

    这几天翻看python语法,看到装饰器这里着实卡了一阵,最初认为也就是个函数指针的用法,但仔细研究后发现,不止这么简单. 首先很多资料将装饰器定义为AOP的范畴,也就是Aspect Oriented ...

  9. ESX虚拟机文件列表详解

    http://jackiechen.blog.51cto.com/196075/210492 关闭状态时的文件列表: *-flat.vmdk:虚拟机的原始磁盘文件,包含整个虚拟机镜像.   *.nvr ...

  10. IDL中File_Search函数用法详解(转)

    来自:http://blog.sina.com.cn/s/blog_764b1e9d01014ajp.html 在利用IDL进行批处理时,通常用到file_search函数进行输入路径文件的搜索,现根 ...