C/C++ Question [SOLVED] How to assign value to Class Member from local Callback

rwblinn

Well-Known Member
Licensed User
EDIT: Solved = See post #6. Note: Removed the attachement as the reworked B4R library will be shared in the B4R Libraries forum.

This is question is related to the partial wrapping of the ESP32 lib Legoino to B4R lib rLegoinoBoost.
The lib Legoino requires callbacks to access device property values. These are defined as local functions in the rLegoinoBoost.cpp.
In the header rLegoinoBoost.h, property members are defined, like batteryLevel.

Q: How to assign the batteryLevel from the local callback functions defined in the cpp file?
This is the error message from the code below:
C++:
rLegoinoBoost.cpp:241:68: error: cannot call member function 'void B4R::B4RLegoinoBoost::SetBatteryLevel(Byte)' without object
See code snippets.

rLegoinoBoost.h
C++:
namespace B4R {
    //~shortname: LegoinoBoost
    class B4RLegoinoBoost {
        private:
            SubVoidBool StateChangedSub;
            Byte batteryLevel;                                          <== how to update via local callback?
            static void checkForData(void* b);
            PollerNode pnode;
        public:
            ...
            void SetBatteryLevel(Byte level);
            Byte getBatteryLevel();
            ...
     
    };
}

rLegoinoBoost.cpp
See ==> for the problem.
C++:
namespace B4R {
    ...
    Byte batteryLevelLocal;
 
    void B4RLegoinoBoost::SetBatteryLevel(Byte level) { batteryLevel = level; }
    Byte B4RLegoinoBoost::getBatteryLevel() { return batteryLevel; }

    // Callbacks for properties Battery Level & Voltage
    void hubPropertyChangeCallback(void *hub, HubPropertyReference hubProperty, uint8_t *pData) {
      Lpf2Hub *myHub = (Lpf2Hub *)hub;
      if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE) {
==>            // ERROR = How to assign the batterylevel to the class member batteryLevel
rLegoinoBoost.cpp:241:68: error: cannot call member function 'void B4R::B4RLegoinoBoost::SetBatteryLevel(Byte)' without object
==>            B4RLegoinoBoost::SetBatteryLevel(myHub->parseBatteryLevel(pData));
            // Woraround using local var
            batteryLevelLocal = myHub->parseBatteryLevel(pData);
            return;
      }
    }

    // Looper handling movehub connection
    void B4RLegoinoBoost::checkForData(void* b) {
        B4RLegoinoBoost* me = (B4RLegoinoBoost*)b;
        if (MoveHub.isConnecting()){
            MoveHub.connectHub();
            if (MoveHub.isConnected() && !isInitialized){
                // Delay needed because otherwise the message is to fast after the connection procedure and the message will get lost
                delay(50);
                MoveHub.activateHubPropertyUpdate(HubPropertyReference::BATTERY_VOLTAGE, hubPropertyChangeCallback);
                isInitialized = true;
            }
        }
        // Update battery state and other hub properties
        if (MoveHub.isConnected()) {
            // Assing the local var values to the b4r class values
            // TODO: need to find a way how to assign the updated values using the local callback functions and not use below line on every loop
            me->batteryLevel = batteryLevelLocal;
        }
    }
}
 
Last edited:

Daestrum

Well-Known Member
Licensed User
Have you tried
B4X:
SetBatteryLevel(myHub->parseBatteryLevel(pData));

instead of
B4X:
B4RLegoinoBoost::SetBatteryLevel(myHub->parseBatteryLevel(pData));

My reasoning is it will call the method of the current object.
Not tried or tested just seems logical.
 

rwblinn

Well-Known Member
Licensed User
B4X:
SetBatteryLevel(myHub->parseBatteryLevel(pData));

Thanks for the hint.
Yes - that was my very first try = resulting in error which is confusing as the function has been declared.
C++:
rLegoinoBoost.cpp:241:51: error: 'SetBatteryLevel' was not declared in this scope
 

Daestrum

Well-Known Member
Licensed User
The only other thought is like you used further down the code
B4X:
me->SetBatteryLevel(myHub->parseBatteryLevel(pData));
 

rwblinn

Well-Known Member
Licensed User
B4X:
me->SetBatteryLevel(myHub->parseBatteryLevel(pData));
Yes, that one checked also = requires an B4RLegoinoBoost object which relates to the error message in post #1.
The object me is created from the function checkForData parameter void* b.
So indeed seeking how to create an B4RLegoinoBoost object without changing the signature of the callback functions, because these are given by the library being wrapped.
Thanks again for the next hint.
Think it has to do with the Class definition = will explore further...
 

rwblinn

Well-Known Member
Licensed User
This class is used to control a single Lego MoveHUB.
Implemented the global field and initialization plus other properties and enhancements.
The library is working fine.
When ready, will share in the B4R Libraries forum.
Thanks for support.
 
Top