CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)
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)代碼有一點點小長但是信息量很大。
// POD struct struct foo {std::vector<int> a;int b; };// announce requires foo to have the equal operator implemented bool operator==(const foo& lhs, const foo& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b; }// a pair of two ints using foo_pair = std::pair<int, int>;// another pair of two ints using foo_pair2 = std::pair<int, int>;// a struct with member vector<vector<...>> struct foo2 {int a;vector<vector<double>> b; };bool operator==(const foo2& lhs, const foo2& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b; }// receives `remaining` messages void testee(event_based_actor* self, size_t remaining) {auto set_next_behavior = [=] {if (remaining > 1) testee(self, remaining - 1);else self->quit();};self->become (// note: we sent a foo_pair2, but match on foo_pair// that's safe because both are aliases for std::pair<int, int>[=](const foo_pair& val) {cout << "foo_pair("<< val.first << ", "<< val.second << ")"<< endl;set_next_behavior();},[=](const foo& val) {cout << "foo({";auto i = val.a.begin();auto end = val.a.end();if (i != end) {cout << *i;while (++i != end) {cout << ", " << *i;}}cout << "}, " << val.b << ")" << endl;set_next_behavior();}); }int main(int, char**) {// announces foo to the libcaf type system;// the function expects member pointers to all elements of fooannounce<foo>("foo", &foo::a, &foo::b);// announce foo2 to the libcaf type system,// note that recursive containers are managed automatically by libcafannounce<foo2>("foo2", &foo2::a, &foo2::b);// serialization can throw if types are not announced properlytry {// init some test data foo2 vd;vd.a = 5;vd.b.resize(1);vd.b.back().push_back(42);// serialize test datavector<char> buf;binary_serializer bs(std::back_inserter(buf));bs << vd;// deserialize written test data from buffer binary_deserializer bd(buf.data(), buf.size());foo2 vd2;uniform_typeid<foo2>()->deserialize(&vd2, &bd);// deserialized data must be equal to original inputassert(vd == vd2);// announce std::pair<int, int> to the type systemannounce<foo_pair>("foo_pair", &foo_pair::first, &foo_pair::second);// libcaf returns the same uniform_type_info// instance for the type aliases foo_pair and foo_pair2assert(uniform_typeid<foo_pair>() == uniform_typeid<foo_pair2>());}catch (std::exception& e) {cerr << "error during type (de)serialization: " << e.what() << endl;return -1;}// spawn a testee that receives two messages of user-defined typeauto t = spawn(testee, size_t{2});{ // lifetime scope of self scoped_actor self;// send t a fooself->send(t, foo{std::vector<int>{1, 2, 3, 4}, 5});// send t a foo_pair2self->send(t, foo_pair2{3, 4});}await_all_actors_done();shutdown(); }一開始看,就是聲明了兩種結構體。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我寫了一個很難看的代碼。
#include <vector> #include <iostream> #include "caf/all.hpp" #include "caf/io/all.hpp" using std::cout; using std::endl; using std::vector; using std::map; using std::pair; using namespace caf;struct foo {std::vector<vector<map<int,pair<int,int>>>> a;int b; }; bool operator==(const foo& lhs, const foo& rhs) {return lhs.a == rhs.a && lhs.b == rhs.b; } // receives `remaining` messages void testee(event_based_actor* self) {self->become ([=](const foo& val) {aout(self)<<"get it"<<endl;}); } int main(int, char**) { // announce<foo2>("foo2", &foo2::a, &foo2::b);announce<foo>("foo", &foo::a, &foo::b);auto actor = spawn(testee);caf::io::publish(actor,10000);{ // lifetime scope of self scoped_actor self;auto remoter = caf::io::remote_actor("localhost", 10000);self->send(remoter, foo{std::vector<vector<map<int,pair<int,int>>>>{},1,});}await_all_actors_done();shutdown(); }結果為
不得不服還是很方便的!
碼字不容易,求粉絲~互粉呀~
?
轉載于:https://www.cnblogs.com/zhejiangxiaomai/p/5259625.html
總結
以上是生活随笔為你收集整理的CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ajaxSubmit()上传
- 下一篇: 深入浅出的mysql第三版和第二版的区别