2017-12-21 22 views
1

多くの構造を持つ構造を別のコントローラーに送信したいとします(コントローラーと同じものではなく、別のアーキテクチャーを持つもの)。 私は、利用可能な発明されたシリアライズ方法を使用せずに、データを送信するための並べ替えを開発する必要がありました。 パディングされたバイトがどこに追加されて他のコントローラに送信する前にそれらを削除できるのかを知るにはどうすればよいですか? 他のコントローラがデータの送信バイトから構造のすべてのメンバーを再構築できるように、どのようにメタデータを実装できますか? その他の要点も歓迎します。コントローラー間で構造を送信する

答えて

0

TLVタイプのコード体系を使用することを検討してください。通常、TLVはType Length Valueと呼ばれます。

通常要素が

#pragma pack(1) 
    typedef struct _tlv_node { 
      uint8_t type; 
      uint16_t length; 
      uint8_t value[0]; 
    }tlv_node; 

のように見えるこれは、符号化と復号化の流れの多くのためにかなり標準であり、あなたは、構造体のいずれかのタイプにそれを拡張することができます。多くのオープンソースコードではこれが実装されているため、サンプル実装の欠如はありません。

+1

コードはb0rkenで無効です。値の1つの要素を特に上回るものは未定義の振る舞いを持ち、 'pack'は非常に高価なハックです。 –

+0

1999年にようこそ、私たちはもう安全でない "struct hack"を使用する必要はありません。 – Lundin

+0

@ lundinあなたはここで自分自身のことを話していますが、プラグマパックは一般的なプロセッサの一般的なツールチェーンでサポートされているハックではなく、それが指し示すメモリが特定のレイアウトを持っていることを確認する1つの理由があります。またはネットワークパケット。梱包時の嘲笑は、プロセッサの束が依然としてsigbusである場合にはかなり90です。インターネット上で論争することは決して古くなることはありません。私はあなたの答えが好きです。 – amritanshu

3

完全に移植可能なシリアル化/逆シリアル化は非常に手動です。あなたは構造体のメンバーを通過してコピーします。とにかくstructメンバーごとにいくつかの "手作業コーディング"を行う必要があることを意味するので、それはほとんど埋め合わせを意味しないので、offsetofを使用してパディングを見つけることができます。

#pragma pack(1)などが理想的ではありません。ストラクチャは理由でパックされており、パディングを無効にする移植性のある手段はありません。 8ビットや16ビットのような小さなCPUでは実現可能ですが、移植性の高いコードでは実現できません。

重要なのは、データがどのように格納されるかを示す、明確に定義されたネットワークプロトコルを持つことです。には、エンディアンがです。つまり、送信者、プロトコル、受信者はすべてエンディアンを持ち、必ずしも同じであるとは限りません。

(伝統的に、データ・プロトコルでは、XORゲートによるハードウェアCRCチェックを実装するのが唯一の理由でビッグ・エンディアンが使用されることがよくありますが、現在はほとんど問題ではありません。 。)

+0

要件に応じて、「明確に定義されたネットワークプロトコル」はASCIIベースでも可能です。このような転送は、バイナリプロトコルよりも安全で実装が容易で、監視/デバッグが容易です。 – tofro

+1

@tofro ASCIIプロトコルとは、データが膨らみ、エンコード/デコードが遅いということです。あなたがそれらを使用する唯一の理由は、監視が非プログラマによって行われるべき場合です。私は "ATコマンド"のような古いやり方の実装を避けるだろう。 – Lundin

+0

インターネットと呼ばれるもののほとんどではないにしても、そのような「古いもの」に基づいています。それほど悪くはありませんか? – tofro

関連する問題