일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- DockerVolume
- docker
- Wake On Lan
- dotnet Core
- .netCore Install
- Ubuntu VirtualBox
- VirtualBox Ubuntu
- IOCP 클라이언트
- MySQL
- IOCP 서버
- wol
- docker desktop
- Docker오류
- mongodb pss
- 도커마운트
- Volume Mount
- .netCore3.1
- Winsock
- Ubuntu Server VirtualBox
- IOCP
- .dotnet Core 3.1 Install
- DockerDesktop
- DockerWindows
- 윈도우10 Wake On Lan
- mongodb readonly
- 윈도우10 WOL
- 우분투서버가상머신
- 닷넷코어
- mongo docker
- ubuntu .net Core
- Today
- Total
;
[FlatBuffers] 플랫버퍼란 무엇인가? 본문
FlatBuffers
FlatBuffers 는 C, C++, C#, GO, Java, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust를 위한
크로스 플랫폼 직렬화 라이브러리 입니다.
FlatBuffers 플랫버퍼를 사용하는 이유?
- 패킹/언 패킹 없이 직렬화 된 데이터에 엑세스
- 메모리 효율성 및 속도 증가
- 생성된 코드가 작고 단일 Header 파일로 쉽게 통합을 할 수 있습니다.
- 모든 언어에서 사용하기 편리하게 제공 합니다.
- 크로스 플랫폼, 종속성 없이 사용이 가능합니다.
FlatBuffers 사용 방법 :
1. FlatBuffer Schema 작성
- Schema를 작성 하게 되면 자신이 원하는 플랫폼으로 라이브러리가 생성 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | namespace MyGame.Sample; enum Color:byte { Red = 0, Green, Blue = 2 } union Equipment { Weapon } // Optionally add more tables. struct Vec3 { x: float ; y: float ; z: float ; } table Monster { pos:Vec3; mana: short = 150; hp: short = 100; name:string; friendly: bool = false ( deprecated ); inventory:[ubyte]; color:Color = Blue; weapons:[Weapon]; equipped:Equipment; } table Weapon { name:string; damage: short ; } root_type Monster; |
위 내용은 FlatBuffers의 Schema 예제 중 하나인 monster.fbs 파일의 코드 입니다.
코드에서 보시는 바와 같이 직관적이게 보입니다.
간단히 설명을 하면 Monster라는 Table에 "위치, 마나, 체력, 이름, 친구, 인벤토리, 색상, 무기, 장비" 등이 들어 가 있습니다.
위 와 같이 테이블을 작성하고, 생성을 하시면 각 플랫폼에 맞게 라이브러리가 생성이 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | // automatically generated by the FlatBuffers compiler, do not modify #ifndef FLATBUFFERS_GENERATED_FLATBUFFERS_MYGAME_SAMPLE_H_ #define FLATBUFFERS_GENERATED_FLATBUFFERS_MYGAME_SAMPLE_H_ #include "flatbuffers/flatbuffers.h" namespace MyGame { namespace Sample { struct Vec3; struct Monster; struct Weapon; enum Color { Color_Red = 0, Color_Green = 1, Color_Blue = 2, Color_MIN = Color_Red, Color_MAX = Color_Blue }; inline Color (&EnumValuesColor())[3] { static Color values[] = { Color_Red, Color_Green, Color_Blue }; return values; } inline const char **EnumNamesColor() { static const char *names[] = { "Red" , "Green" , "Blue" , nullptr }; return names; } inline const char *EnumNameColor(Color e) { const size_t index = static_cast < int ><span style= "font-family: "맑은 고딕", sans-serif;" >(e); return EnumNamesColor()[index]; } enum Equipment { Equipment_NONE = 0, Equipment_Weapon = 1, Equipment_MIN = Equipment_NONE, Equipment_MAX = Equipment_Weapon }; template <> inline const Weapon *Monster::equipped_as</span><weapon><span style= "font-family: "맑은 고딕", sans-serif;" >() const { return equipped_as_Weapon(); } inline flatbuffers::Offset</span><monster><span style= "font-family: "맑은 고딕", sans-serif;" > CreateMonster( flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos = 0, int16_t mana = 150, int16_t hp = 100, flatbuffers::Offset</span><flatbuffers::string><span style= "font-family: "맑은 고딕", sans-serif;" > name = 0, flatbuffers::Offset</span><flatbuffers::vector<uint8_t><span style= "font-family: "맑은 고딕", sans-serif;" >> inventory = 0, Color color = Color_Blue, flatbuffers::Offset</span><flatbuffers::vector<flatbuffers::offset<weapon><span style= "font-family: "맑은 고딕", sans-serif;" >>> weapons = 0, Equipment equipped_type = Equipment_NONE, flatbuffers::Offset</span>< void ><span style= "font-family: "맑은 고딕", sans-serif;" > equipped = 0) { MonsterBuilder builder_(_fbb); builder_.add_equipped(equipped); builder_.add_weapons(weapons); builder_.add_inventory(inventory); builder_.add_name(name); builder_.add_pos(pos); builder_.add_hp(hp); builder_.add_mana(mana); builder_.add_equipped_type(equipped_type); builder_.add_color(color); return builder_.Finish(); } inline flatbuffers::Offset</span><monster><span style= "font-family: "맑은 고딕", sans-serif;" > CreateMonsterDirect( flatbuffers::FlatBufferBuilder &_fbb, const Vec3 *pos = 0, int16_t mana = 150, int16_t hp = 100, const char *name = nullptr, const std::vector</span><uint8_t><span style= "font-family: "맑은 고딕", sans-serif;" > *inventory = nullptr, Color color = Color_Blue, const std::vector</span><flatbuffers::offset<weapon><span style= "font-family: "맑은 고딕", sans-serif;" >> *weapons = nullptr, Equipment equipped_type = Equipment_NONE, flatbuffers::Offset</span>< void ><span style= "font-family: "맑은 고딕", sans-serif;" > equipped = 0) { return MyGame::Sample::CreateMonster( _fbb, pos, mana, hp, name ? _fbb.CreateString(name) : 0, inventory ? _fbb.CreateVector</span><uint8_t><span style= "font-family: "맑은 고딕", sans-serif;" >(*inventory) : 0, color, weapons ? _fbb.CreateVector</span><flatbuffers::offset<weapon><span style= "font-family: "맑은 고딕", sans-serif;" >>(*weapons) : 0, equipped_type, equipped); } inline const MyGame::Sample::Monster *GetMonster( const void *buf) { return flatbuffers::GetRoot</span><mygame::sample::monster><span style= "font-family: "맑은 고딕", sans-serif;" >(buf); } inline bool VerifyMonsterBuffer( flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer</span><mygame::sample::monster><span style= "font-family: "맑은 고딕", sans-serif;" >(nullptr); } inline void FinishMonsterBuffer( flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset</span><mygame::sample::monster><span style= "font-family: "맑은 고딕", sans-serif;" > root) { fbb.Finish(root); } } // namespace Sample } // namespace MyGame #endif // FLATBUFFERS_GENERATED_FLATBUFFERS_MYGAME_SAMPLE_H_</span></mygame::sample::monster></mygame::sample::monster></mygame::sample::monster></flatbuffers::offset<weapon></uint8_t></void></flatbuffers::offset<weapon></uint8_t></monster></void></flatbuffers::vector<flatbuffers::offset<weapon></flatbuffers::vector<uint8_t></flatbuffers::string></monster></weapon></int> |
위 예제는 monster.fbs Schema를 C++로 컴파일 하여 나온 Header 파일 중 일부를 지운 내용 입니다.
Schema에서 사용 할 수 있는 문법은 아래와 같이 제공 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | schema = include* ( namespace_decl | type_decl | enum_decl | root_decl | file_extension_decl | file_identifier_decl | attribute_decl | rpc_decl | object )* include = include string_constant ; namespace_decl = namespace ident ( . ident )* ; attribute_decl = attribute ident | "ident<tt><span style=" font-family: "맑은 고딕", sans-serif; ">" ; type_decl = ( table | struct ) ident metadata { field_decl+ } enum_decl = ( enum ident [ : type ] | union ident ) metadata { commasep( enumval_decl ) } root_decl = root_type ident ; field_decl = ident : type [ = scalar ] metadata ; rpc_decl = rpc_service ident { rpc_method+ } rpc_method = ident ( ident ) : ident metadata ; type = bool | byte | ubyte | short | ushort | int | uint | float | long | ulong | double | int8 | uint8 | int16 | uint16 | int32 | uint32| int64 | uint64 | float32 | float64 | string | [ type ] | ident enumval_decl = ident [ = integer_constant ] metadata = [ ( commasep( ident [ : single_value ] ) ) ] scalar = integer_constant | float_constant object = { commasep( ident : value ) } single_value = scalar | string_constant value = single_value | object | [ commasep( value ) ] commasep(x) = [ x ( , x )* ] file_extension_decl = file_extension string_constant ; file_identifier_decl = file_identifier string_constant ; integer_constant = -?[0-9]+ | true | false float_constant = -?[0-9]+.[0-9]+((e|E)(+|-)?[0-9]+)? string_constant = \ ".*?\\" ident = [a-zA-Z_][a-zA-Z0-9_]*</span></tt> |
출처 : FlatBuffers Grammar of the schema language
2. Schema 컴파일 방법
Schema를 자신이 원하는 플랫폼에 컴파일 방법은 우선 Release된
FlatBuffers를 다운로드 부 터 시작 됩니다.
다운로드 주소 : Github FlatBuffers Releases
↑ 다운로드 된 파일을 보시면 flatc 라 는 파일이 있습니다.
↑ 해당 파일을 풀어 놓으시고, 해당 위치에 작성된 Schema인 *.fbs를 같이 놓으시면 됩니다.
↑ 그 뒤 Shift+오른쪽 마우스를 클릭하여 "여기서 명령창 열기"를 클릭하시면 됩니다.
flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES...
[ -- FILES...]
↑ Schema를 원하시는 언어로 컴파일 하시려면 컴파일 방법을 알아야 합니다.
GENERATOR OPTIONS : 원하는 언어
1 2 3 4 5 6 7 8 9 10 11 12 13 | --cpp, -c : Generate a C++ header for all definitions in this file (as filename_generated.h). --java, -j : Generate Java code. --csharp, -n : Generate C# code. --go, -g : Generate Go code. --python, -p: Generate Python code. --js, -s: Generate JavaScript code. --ts: Generate TypeScript code. --php: Generate PHP code. --grpc: Generate RPC stub code for GRPC. --dart: Generate Dart code. --lua: Generate Lua code. --lobster: Generate Lobster code. --rust, -r : Generate Rust code. |
-o PATH : 저장될 위치
-I PATH : Schema *.fbs가 있는 위치
ex) Schema를 통하여 C++로 컴파일을 한다.
- flatc --cpp -o ./cpp/ ./monster.fbs
ex) Schema를 통하여 C#으로 컴파일을 한다.
- flatc --csharp -o ./csharp/ ./monster.fbs
↑ 입력을 하신 후 Enter 를 칩니다.
↑ cpp 폴더 안에 monster_generated.h 파일이 생성이 됩니다.
매번 코드를 입력하기 위하여 사이트를 들어오셔서 복사를 하시는 분들을 위하여
번호 하나만 치시면 자동으로 컴파일 되는 프로그램을 직접 만들었습니다.
↑ input_fbs에 "FlatBuffers.fbs"로 파일을 저장하신 후 "MakeFlatBuffers.bat" 파일을 실행 시키셔서
자신이 원하는 언어 번호를 치시면 "output_file"에 원하시는 언어로 자동 컴파일 됩니다.
다운로드 : FlatBuffers_MakeFile.zip
3. 컴파일 된 Header를 적용 시켜 보자.
- C++ 예제를 설명해 드리겠습니다.
↑ 컴파일 된 Header 파일을 자신이 만든 프로젝트에 붙어넣기 합니다.
↑ Header 파일을 불러오셔도 빨간 줄 이 나오면서 빌드를 할 수가 없습니다.
이유는 FlatBuffers를 사용하기 위한 사용자 Schema를 컴파일한 Header는 준비 되었지만
FlatBuffers에 필요한 Header 파일이 들어가 있지 않기 때문 입니다.
↑ Source Code를 받으신 후
↑ 압축을 푸신 후 해당 폴더의 "include" 폴더에 들어가셔서 "flatbuffers"를 header파일을 복사 해놓은 위치에 같이 넣어 주세요.
↑ 넣으신 후 빌드를 하시면 정상적으로 빌드가 되실 겁니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <iostream><span style="font-family: "맑은 고딕", sans-serif;"> #include "FlatBuffers_generated.h" using namespace MyGame::Sample; int main() { //--------------------------------------------------------------------------------------------------------------- // FlatBuffers 데이터 만들기. // FlatBuffers 빌드를 선언 해줍니다. flatbuffers::FlatBufferBuilder builder; // 몬스터에게 검, 도끼 에 대한 무기와 데미지를 넣어 줍니다. auto weapon_one_name = builder.CreateString( "Sword" ); short weapon_one_damage = 3; auto weapon_two_name = builder.CreateString( "Axe" ); short weapon_two_damage = 5; // `CreateWeapon` 명령어를 사용하여 모든 필드가 설정된 무기를 만듭니다. auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); // `std::vector`에서 FlatBuffer의 `vector`를 만듭니다. std::vector</span><flatbuffers::offset<weapon><span style= "font-family: "맑은 고딕", sans-serif;" >> weapons_vector; weapons_vector.push_back(sword); weapons_vector.push_back(axe); auto weapons = builder.CreateVector(weapons_vector); // 몬스터에 필요한 좌표, 이름, 인벤토리 등을 만들어 줍니다. auto position = Vec3(1.0f, 2.0f, 3.0f); auto name = builder.CreateString( "MyMonster" ); unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto inventory = builder.CreateVector(inv_data, 10); // 모든 데이터가 설정된 후 몬스터 생성을합니다. auto orc = CreateMonster(builder, &position, 150, 80, name, inventory, Color_Red, weapons, Equipment_Weapon, axe.Union()); builder.Finish(orc); // 해당 데이터를 빌드 합니다. //--------------------------------------------------------------------------------------------------------------- // FlatBuffers 데이터 받기 // monster라는 변수에 빌드된 데이터를 받아서 불러옵니다. auto monster = GetMonster(builder.GetBufferPointer()); std::cout << "몬스터 체력 : " << monster->hp() << std::endl; std::cout << "몬스터 마나 : " << monster->mana() << std::endl; std::cout << "몬스터 이름 : " << monster->name()->str() << std::endl; std::cout << "몬스터 위치 : " << monster->pos()->x() << ", " << monster->pos()->y() << ", " << monster->pos()->z() << std::endl; }</span></flatbuffers::offset<weapon></iostream> |
↑ "monster.fbs" Schema를 C++로 컴파일 하여 Monster 테이블에 값을 넣고 불러오는 예제 코드입니다.
↑ 예제 코드를 실행하면 위와 같이 값을 출력해 줍니다.
예제 코드 다운로드 (Visual Studio 2017 컴파일 ) : FlatBuffersTest.zip
'C, C++, C#' 카테고리의 다른 글
정규식 자동 완성 사이트 (0) | 2018.01.25 |
---|---|
C# 비동기 클라이언트 소켓 예제 [ C# Asynchronous Client ] (2) | 2017.07.17 |
C# HttpWebRequest 웹 파싱하기 (0) | 2017.06.28 |
C# 특정글자 파싱하기 SplitParsing (2) | 2017.06.28 |
C언어 ODBC를 이용하여 특정 아이디의 데이터 찾아 뿌려주기 (0) | 2017.05.31 |