unionを使い倒そう
というわけでもないのですが・・・今、えるいーだーの電文を色々いじっていてそういえばunionを使ってコーディングをサボ・・・楽にしようとちょっとunionを使っているのですがみんなどんなときに使ってるんだろうとか気になったので私のunionの使い方の紹介です
#include<Arduino.h>
#include<vector>
struct TBleMsg_Head
{
uint8_t Length; //!< 電文長
uint8_t serialNo; //!< 連番
// 何か色々
uint8_t rslv[2]; //!< 未使用
};
struct TBleRcvMsg_OnOff
{
TBleMsg_Head head; //!< 電文ヘッダ
uint8_t commond; //!< コマンド(on or off)
uint8_t num; //!< 何番目のLEDを制御するか
//...色々なデータ
};
union URcvData {
TBleMsg_Head head; //!< ヘッダデータ
// LED
TBleRcvMsg_OnOff ledCommon; //!< LEDのONOFF
//...色々な電文の構造体
uint8_t data[0]; //!< 解析したいデータの先頭アドレス @details このバッファにデータを詰めて、他の構造体で解析しやすいようにする
};
void hoge()
{
std::vector<uint8_t> data = pCharacteristic->getValue(); // 受信したデータの先頭アドレス
size_t size = data.size(); // 受信したデータサイズ
URcvData *uRcvData = (URcvData *)data.data(); // データを解析用のヘッダに代入すると、ヘッダの構造体で読めるようになる
auto lednumber = uRcvData->ledCommon.num; // LEDの番号
}
このように受信電文を受けたときにメモリを自分で展開しないで構造体にunionを使ってマッピングしてしまうという・・・
TBleMsg_Head:電文ヘッダです
TBleRcvMsgOnOff:LEDのON/OFFを制御する構造体
URcvData:これが電文をマッピングするためのunion共用体。構造体を定義して最後にuint8_t data[0]等とふざけた記述があります
どう使う?
関数hoge()の先頭でBleのクラスから受信データを引っ張り出します
で、問題の・・・
URcvData *uRcvData = (URcvData *)data.data();
という行で取り出したデータの先頭のポインタをuRcvDataに代入します
んで、そのデータを取り出してみるとちゃんと構造体から取り出せますというお話し
昔のc言語ではよくやってましたね
まあ、えるいーだーのボードではこんなことをやってコーディング量を減らしているわけです
ちょっと皆さんのコーディング量を減らす工夫を教えていただけると助かるかなぁと思っています
おまけ
※間違っても会社のプログラムではやらないようにして下さい。個人開発で手数を減らすためのunionの使い方です
普通の静的解析ツールでこんなことをやったらまず通りません
移植するときも問題が多発します。
仕事のプログラムではちゃんと1メンバ毎に変換するようにして下さい。
おしまい
コメント
コメントを投稿