土屋つかさの技術ブログは今か無しかスマートフォン用の表示で見る土屋つかさの技術ブログは今か無しか土屋つかさが主にプログラミングについて語るブログです。今回はFlatBuffersでシリアライズされたバイナリデータが、実際にどのようなルールでメモリにレイアウトされているかを解説します。使用するデータ前回作成したバイナリデータの、メモリレイアウトを以下に示します。・"$00"は、バイナリデータ上の0番地を示します(10進数です)。"$"を頭につけるのは分かりやすさの為で、本来こんな記法はありません(多分)。・1バイト単位、各バイトを10進数で列挙しています。・FlatBuffersは常にリトルエンディアンで配置されます。0"は"12"のことです。・データ中の各所に未使用領域があります。これらはvTableや参照へのアクセス時にメモリアライメントフォールトを避けるために作られたのだと思いますが、検証していないのでひとまず無視しています。|rootテーブルの相対アドレス($00+12=$12)$00からの4バイトは、rootオブジェクト(ここではMonsterList)の相対アドレスを示しています。|[+4]Items(相対アドレス($16+4=$20))Headerで示された$12から8バイトがMonsterListオブジェクトになります。「MonsterListオブジェクトが8バイト」という情報は、後述するvTableを先に参照して把握します。最初の4バイトは、MonsterListのvTableへの相対アドレスです。vTableは、そのオブジェクトの各プロパティへのジャンプテーブルが格納されています。vTableの相対アドレスは、通常現在のアドレスからの差分になります。ここでは$12-6で$06がvTableです。次の4バイトは、Itemsへの相対アドレスです。Itemsは要素が複数個からなるVectorなので、ここには相対アドレスが入っています(ポインタや参照と同じです)。|Itemsの相対アドレス(+4)vTableは2バイトの組になります。最初の2バイトはvTable自身のサイズです。ここでは6バイトに指定されていて、$06から$11までがMonsterListのvTableである事を示しています。次の2バイトは、オブジェクト本体のサイズです。ここでは8バイトと定義されています。MonsterListオブジェクトが$12から8バイトのサイズというのはこの指定によります。最後の2バイトは、オブジェクト本体における、Itemsのデータが配置されている場所の相対アドレスになります。$12から+4番地の$16を示しています。$28+4=$32vectorは、最初の4バイトで要素数を示し、続く4バイトごとに各要素への参照が格納されます。|[+12]items[0].name(相対アドレス($72+16=$88))MonsterについてはvTableとオブジェクトをセットで解説します。$24でItems[0]の相対アドレス($24+36=$60)が算出されます。$60にはvTableへの相対アドレスが差分で格納されています($60-(+12)=$48)。この辺りはMonsterListと同じですね。先にvTableを見てみます。$48にvTableのサイズ(12バイト)、$50にオブジェクトのサイズ(16バイト)が格納され、$52、$54、$56、$58にはmana、hp、cost、nameの各フィールドへの(オブジェクトの先頭アドレスからの)相対アドレスが格納されています。$52が(4ではなく)6になっている事に注目してください。$64から2バイトはメモリアラインのために未使用領域になっているため、manaは先頭アドレスから6バイト目に格納されているのです。Monsterオブジェクトの各フィールドは$64から配置されています。mana/hp/costはshort型なので2バイトですが、nameは4バイトで相対アドレスを格納します。|[未使用領域]文字列が格納されている所を見てみましょう。$72+16=$88が文字列が配置されている番地です。最初の4バイトはstringの文字数です(ここでは3)。続く$92~$95の3バイトに文字列が格納されています(コードは常にutf8)。0をアライメントに合わせる意図だと思います)。補足:Monster(1)のvTable参照Monsterは2要素登録されていますが、どちらもスキーマは同じです(当たり前ですが)。解説は省略しますが、items(1)のvTableへの相対アドレスだけわかりにくいので見ておきます。11110000符号アリ4バイト整数として見た場合、これは"-16"を示します。オブジェクト自体よりもvTableの方が後ろアドレスに配置されているので、相対アドレスがマイナスになるわけです(vTableへのアクセス時のみ、相対アドレスが加算ではなく差分になる事に注意してください)。続かないブログ上でのFlatBuffersについての解説はいったんここまでとなります(間違いを見つけたら適宜補足しようと考えています)。ここからは、技術書典用の原稿作業に進みます。ここまでの記事をベースに、FlatBuffersを使い倒すのに必要な情報をできるだけ詰め込んだ本にしたいと思っているので、読みたい方は完成を祈っていてください。シリアライズ/デシリアライズのサンプ...いよいよデータのシリアライズ/デシリアライズを実行します。パスの詳細」...(2018/12/20追記)下記で指摘しているドキュメントはUnity5.3の...2017-07-20Parsletのpp出力結果についてparsletの構文解析結果をppすると、以下のようなハッシュが出力...2016-09-07司エンジンで2Dアクションゲームを作ってみる(その4・ひとまず完結編)スクロールに対応できたのでひとまずここまで。VS2017からVS2019へ環境を移動する。新InputSystemを試そうとしてハマッた話Archiveスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。