スキップしてメイン コンテンツに移動

c/c++でunionを使う

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メンバ毎に変換するようにして下さい。

おしまい


コメント

このブログの人気の投稿

RAM DISKを使ってみた(使ったのはImDisk)

GWだし、まあちょっとラムディスクを入れてみました うちのPCはWindows11 使ったのはImDiskというRAM Disk。 まあ、この辺のインストールとかはあちこちで解説してる人がいるので適当にぐぐってくださいな で、とりあえずベンチマーク なかなかいいスピードだ で、大抵の人はブラウザのキャッシュをRAMディスクにするといいよ・・・と言うけど そもそもメインドライブがNVMeのSSDを使っている状態で、体感速度なんか上がらない(使い終わったキャッシュを再起動したら綺麗さっぱり捨て去ってくれるという利点はある)  うちで一番効果があるのは Adobe Audition というアプリ これが結構高速化する(キャッシュをちゃんとRAMディスクにしたら・・・だけど) ハイレゾ音源だと、1時間の音源が何かする度に4GBのファイルを作られてしまう なので、RAM DISKにすると、結構編集時間を短縮できる Premiere Rushも出力先をRam Diskにしておいて終わったら、SSDにコピーすると言う事をやるとかなりスピードアップになる 実はうちのPCは普段は99%のパワーで動作していて、CPUのターボブーストが掛からないようになっている 大体3.6GHz当たりで安定してるのだけど、これを100%にするとターボブースト機能がONになって一部のコアが4.5とか4.8GHzまで上がる まあ、毎回電源オプションをいじる事になるのだけどさ・・・ そうしてベンチを取ると こんな感じ とは言え、ブーストしてるからと行ってRam Diskのスピードの差を体感する事はさすがに無理 ・・・と言うかフォトショでもRAM DISKにしてよかった・・・と言うほど変わらない SSDの性能が上がってきたしもし次にPCを買い換えたらRAM DISKよりSSDの方が速いかもね  

.NET MAUI BLE(Bluetooth Low Energy)も上手く行った

2023/10/11更新 ↓こちらの記事で更新しれました。 .NET MAUI PLUGIN BLEがWindows(10/11)に対応してた Windows対応 イヤッッホォォォオオォオウ Bluetooth LE plugin for Xamarin &amp; MAUI がWindowsに対応してた~ nugetでver3.00をみんな早速ゲットだ。   ちなみにこちらはAndroid版のサンプルアプリ   GitHub...   [ブログカード風リンクタグ作成] ------------------------------------------------------------------------------ 昔、スマホとESP32の接続確認用に作ったプログラムをXamarinからMAUIに移植したら動いちゃった   まあ、ESP32からスマホへの一方通行なアプリなんだけど 面倒くさいので github に公開した 下手くそなコード書きやがってとか思われそう 「間違ってるぞこのやろう」というのを見つけたら教えてくれると嬉しいです 要素技術の調査はこれで完了かな

.NET MAUIでスプラッシュスクリーン Android12で地獄を見る

まずは起動するところから・・・・  スプラッシュスクリーンだぬ マイクロソフトのサイト 見てると簡単そう(実際簡単で細かい事を気にしなければsvgファイルを用意して1行だけ書き換えておしまい)   なんかプロジェクトファイルに自動で記述されるらしい よし、プロジェクト作った                     つーか、もうスプラッシュがあるんだけど・・・・ そして自作のsvgファイル くうっ・・・デザインセンスない・・・・   それはともかく、このSVGファイルを Resources\Images にドラッグ&ドラッグ プロジェクトを右クリックして「プロジェクトファイルの編集」 して、編集できるようになったプロジェクトファイルを 自分のプロジェクトファイルに書き換える <MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="168,168" /> ↓ <MauiSplashScreen Include="Resources\Splash\ splashtestmaui .svg" Color="#512BD4" BaseSize="168,168" />   とりあえずAndroidで実行 お、おう・・・・ まあ最初はこんなもんよね 最初に紹介したマイクロソフトのサイトでもBaseSizeを書き換えてくださいって言ってるし 言われたとおりに <MauiSplashScreen Include="Resources\Splash\splashtestmaui.svg" Color="#512BD4" BaseSize=" 320,600 " /> 書き換えてみると いい感じじゃーん じゃあアンドロイドのバージョン毎に試してみよう   Android 7 Android 11 Android 12 Android 13 ...