私が取り組んでいる組み込みアプリケーションでは、シリアルポートを介して送信するために、いくつかの異なるオブジェクトからのデータをパケット化する必要があることがよくあります。同様に、データはいくつかの異なるオブジェクトに書き込む必要があるシリアルポートに送られます。
互換性の理由から、パケット内のデータの順序付けでは、1つのオブジェクトに関連付けられたすべてのデータをパケット内に連続して配置することはできません。そのため、各オブジェクトのデータなどを簡単にベクトル化して、すべてをパケットに入れることはできません。
パケットクラスが送受信されたパケットを作成/デコードするために使用する非常に多くのゲッター/ミューテーターを使用して、適切な機能を実現できます。しかし、これはあまりエレガントではないようです。
パケットクラスを、データをプル/書き込みするクラスのフレンドにすることはできますが、オブジェクト指向の原則に違反するため、フレンドの使用は避けるように常に言われていました。
理想的には、実際のアプリケーションを処理するクラスは、パケットクラスについて何も知らず(そして、それ専用のゲッター/ミューテーターを提供する必要はありません)、更新の間にパケットが入った場合、単に新しいデータを持ちます。
起動時に関連するメンバー変数への参照またはポインターをパケットクラスに渡すことができるかもしれないと思いましたが、すべてのメンバーが同じサイズではないため、これも注意が必要です。おそらく、サイズ情報も渡すことができますか?パケットクラスがコンストラクターに対して膨大な量の引数を取る必要がないように、メンバーへのvoidポインターとメンバーペアのサイズのリストをベクトル化する方法はありますか?
この問題をどれだけうまく説明したかはわかりませんが、それが役立つ場合は、説明と詳細情報を提供できます。アイデアをありがとうございました。
現在のtxパケットクラスの省略例:
class PacketTx {
private:
uint8_t buffer[MAX_PACKET_SIZE]; // MAX_PACKET_SIZE is 200
public:
PacketTx(object1 *firstObject,
object2 *secondObject,
object3 *thirdObject
// ...etc...
)
void sendPacket(void);
};
void PacketTx::sendPacket(void) {
uint32_t i = 0;
int16_t tempVar1 = firstObject->getVar1();
uint32_t tempVar2 = secondObject->getVar2();
uint8_t tempVar3 = firstObject->getVar3();
int32_t tempVar4 = thirdObject->getVar4();
// ...etc...
memcpy(buffer + i, &tempVar1, sizeof(tempVar1));
i += sizeof(tempVar1);
memcpy(buffer + i, &tempVar2, sizeof(tempVar2));
i += sizeof(tempVar2);
memcpy(buffer + i, &tempVar3, sizeof(tempVar3));
i += sizeof(tempVar3);
memcpy(buffer + i), &tempVar4, sizeof(tempVar4));
i += sizeof(tempVar4);
// ...etc...
for(uint32_t j = 0; j < i; ++j)
putc(static_cast<char>(buffer[i]));
}
この例にはヘッダーやチェックサムなどは含まれていませんが、頭痛の原因となっているものの基本的な考え方がわかるはずです。