スタック・オーバーフロー Asked on September 1, 2021
ESP32というCPUの開発環境上のBLEを扱おうと思っているのですが
その中でコールバッククラスの扱いがわからなくて困っています
VSCode + Platoform IOと言う環境です
もとはAruduino形式のプログラムです(setupとloopがあらかじめ決められている)
元のプログラムではクラスでは無く、直接CPP上で記載されていて、プログラムは以下のようになっています
//データを受信するとMyCallbaksがコールされ、onWrite関数内の命令を実行する
//https://dev.classmethod.jp/articles/esp32_ble_debug_tool/
//こちらのサンプルを使用
class MyCallbacks: public BLECharacteristicCallbacks {//●コールバッククラスの本体
void onWrite(BLECharacteristic *pCharacteristic) {//●onWriteが元のクラス内でvirtualで宣言されていて、この関数を自作して受信したデータの値を取り出す
uint8_t* iData = pCharacteristic->getData();
char str[100];
for(int i=0;i<100;i++){
sprintf(str,"data=%2x",*iData);
iData++;
Serial.print(str);
Serial.print(" ");
}
}
};
pCharacteristic->setCallbacks(new MyCallbacks());//●ここでコールバッククラスを登録
それをBLE関連のクラスにまとめてみようと思ったのですが
と言うところで躓いています
以下のように記述してみたのですがそこから先がどのように記述すればいいのか・・・
Class BleOreyou{
public:
void OnWrite2(BLECharacteristic *pCharacteristic);
//..省略
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {//●この関数をcpp側に記述したい
OnWrite2(pCharacteristic); //●BleOreyouクラスに渡してデータ操作、他のクラスへのイベントの起点にしたい
#if 0
uint8_t* iData = pCharacteristic->getData();
char str[100];
for(int i=0;i<100;i++){
sprintf(str,"data=%2x",*iData);
iData++;
Serial.print(str);
Serial.print(" ");
}
#endif
};
}
A1. そもそも論として virtual
な関数をヘッダファイルにて関数定義してもインライン展開されることは期待できない(というより不可能)なので、ごく普通に「ヘッダファイルでクラス定義とメンバ関数宣言」「 CPP ファイルでメンバ関数定義」すればよいだけのことです。
-- hoge.h --
// クラス定義
class derived1_type : public base_type {
// メンバ関数宣言
virtual void OnEvent(event_arg_type& ev);
};
-- hoge.cpp ---
#include "hoge.h"
void derived1_type::OnEvent(event_arg_type& ev) {
// 何か処理
}
A2. なにをどう渡すのか微妙に不明ですが、この手のコールバックの仕組みというのは
ライブラリというかフレームワークというか側に
bool framework_type::register_callback(base_type& r) { ... }
のような関数があるのが普通です。となると
コールバックしてもらう側(フレームワークのユーザー)の責務は
base_type
派生クラスのインスタンスを用意する(コールバックをしてもらう必要がある間ずっと有効でなければならない:ウィンドウのメンバとかにする必要がある)register_callback()
にその参照を渡してフレームワーク内に保持してもらうunregister_callback()
などの手段でやめてもらうコールバックする側(フレームワーク自体)の処理は
this
の仮想関数を呼び出すつまりフレームワーク側の実装例は
for (base_type& c : callbacklist) {
c.OnEvent(ev);
}
(当該 BLECharactaristicCallbacks
の仕様は未調査)
なのであなたのすべきことは
MyCallbacks
インスタンスを生成してずっと保持するMyCallbacks
インスタンスをコールバックに登録する(以下略)BleOreyou
に当該 MyCallbacks
インスタンスを保持しておけば何も悩むことはないような気がします。っていうか MyCallbacks
を BleOreyou
から分離して別クラスにするから意味なく悩ましくなっているだけの疑いが残ります。
Correct answer by 774RR on September 1, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP