├── .gitignore ├── README.md ├── src ├── proto │ └── Game.proto └── Main.cpp ├── CMakeLists.txt └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cpp-protobuf-example 2 | Simple example of working with Protobuf in C++ 3 | -------------------------------------------------------------------------------- /src/proto/Game.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package me.eax.examples.game; 4 | 5 | enum Spell { 6 | FIREBALL = 0; 7 | THUNDERBOLT = 1; 8 | } 9 | 10 | enum Weapon { 11 | SWORD = 0; 12 | BOW = 1; 13 | } 14 | 15 | message WarriorInfo { 16 | Weapon weapon = 1; 17 | int64 arrows_number = 2; 18 | } 19 | 20 | message MageInfo { 21 | repeated Spell spellbook = 1; 22 | int64 mana = 2; 23 | } 24 | 25 | message Hero { 26 | string name = 1; 27 | int64 hp = 2; 28 | int64 xp = 3; 29 | oneof class_specific_info { 30 | WarriorInfo warrior_info = 4; 31 | MageInfo mage_info = 5; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(protobuf-example) 4 | 5 | include_directories(include) 6 | set(CMAKE_CXX_STANDARD 17) 7 | set(CMAKE_CXX_STANDARD_REQUIRED on) 8 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") 9 | 10 | include(FindProtobuf) 11 | find_package(Protobuf REQUIRED) 12 | include_directories(${PROTOBUF_INCLUDE_DIR}) 13 | 14 | # to find *.bp.h files 15 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 16 | 17 | protobuf_generate_cpp(PROTO_SRC PROTO_HEADER src/proto/Game.proto) 18 | add_library(proto ${PROTO_HEADER} ${PROTO_SRC}) 19 | add_executable(main src/Main.cpp) 20 | target_link_libraries(main proto ${PROTOBUF_LIBRARY}) 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Aleksander Alekseev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace me::eax::examples::game; 8 | 9 | void saveHero(const char* fname, const Hero& hero) { 10 | fstream out(fname, ios::out | ios::trunc | ios::binary); 11 | if(!hero.SerializeToOstream(&out)) 12 | throw runtime_error("saveHero() failed"); 13 | } 14 | 15 | void loadHero(const char* fname, Hero& hero) { 16 | fstream in(fname, ios::in | ios::binary); 17 | if(!hero.ParseFromIstream(&in)) 18 | throw runtime_error("loadHero() failed"); 19 | } 20 | 21 | void printHero(const Hero& hero) { 22 | cout << "Name: " << hero.name() << endl; 23 | cout << "HP: " << hero.hp() << endl; 24 | cout << "XP: " << hero.xp() << endl; 25 | 26 | if(hero.has_mage_info()) { 27 | cout << "Class: mage" << endl; 28 | cout << "Spellbook: "; 29 | for(int i = 0; i < hero.mage_info().spellbook_size(); i++) { 30 | switch(hero.mage_info().spellbook(i)) { 31 | case Spell::FIREBALL: 32 | cout << "fireball, "; 33 | break; 34 | case Spell::THUNDERBOLT: 35 | cout << "thunderbolt, "; 36 | break; 37 | default: 38 | cout << "(unknown spell), "; 39 | break; 40 | } 41 | } 42 | cout << endl; 43 | cout << "Mana: " << hero.mage_info().mana() << endl; 44 | } else if(hero.has_warrior_info()) { 45 | cout << "Class: warrior" << endl; 46 | cout << "Weapon: " << ( 47 | hero.warrior_info().weapon() == Weapon::SWORD ? "sword" : 48 | hero.warrior_info().weapon() == Weapon::BOW ? "bow" : 49 | "(unknown weapon)" 50 | ) << endl; 51 | cout << "Arrows: " << hero.warrior_info().arrows_number() << endl; 52 | } else { 53 | cout << "Class: (unknown class)" << endl; 54 | } 55 | 56 | cout << endl; 57 | } 58 | 59 | int main() { 60 | // Verify that the version of the library that we linked against is 61 | // compatible with the version of the headers we compiled against. 62 | GOOGLE_PROTOBUF_VERIFY_VERSION; 63 | 64 | Hero warrior; 65 | warrior.set_name("eax"); 66 | warrior.set_hp(50); 67 | warrior.set_xp(256); 68 | warrior.mutable_warrior_info()->set_weapon(Weapon::SWORD); 69 | warrior.mutable_warrior_info()->set_arrows_number(15); 70 | 71 | Hero mage; 72 | mage.set_name("afiskon"); 73 | mage.set_hp(25); 74 | mage.set_xp(1024); 75 | mage.mutable_mage_info()->add_spellbook(Spell::FIREBALL); 76 | mage.mutable_mage_info()->add_spellbook(Spell::THUNDERBOLT); 77 | mage.mutable_mage_info()->set_mana(100); 78 | 79 | cout << "Saving heroes..." << endl; 80 | saveHero("eax.dat", warrior); 81 | saveHero("afiskon.dat", mage); 82 | 83 | cout << "Loading heroes..." << endl; 84 | Hero warrior2; 85 | Hero mage2; 86 | loadHero("eax.dat", warrior2); 87 | loadHero("afiskon.dat", mage2); 88 | 89 | cout << endl; 90 | printHero(warrior2); 91 | printHero(mage2); 92 | } 93 | 94 | --------------------------------------------------------------------------------