0

I am creating a class to handle some radio-communication between two radios each connected to an Arduino. I was planning on having a list of functions passed to the class to handle different messages that are received.

My problem is that upon saving an array of functions to a private variable I get the following error:

incompatible types in assignment of 'void (**)(uint8_t*) {aka void (**)(unsigned char*)}' to 'void (* [0])(uint8_t*) {aka void (* [0])(unsigned char*)}'

The only difference being * vs a [0]

Comms.h

    class Comms {
    public:
      //data handlers are arrays of functions that handle data received with an id equal to their index in the array
      typedef void (*DataHandler)(uint8_t data[RH_RF95_MAX_MESSAGE_LEN]);
      Comms(bool isMaster, uint16_t Hz, DataHandler handlers[]);

      void updateRun();

      //first element should be the id, followed by some data
      void queueData(uint8_t data[RH_RF95_MAX_MESSAGE_LEN]);
      int8_t getLastRSSI();

    private:
      RH_RF95 *rf95;

      QueueList<uint8_t[]> messageQueue;
      bool master;
      uint16_t pingDelay;
      DataHandler dataHandlers[];
    };

Comms.cpp trimmed down

#include "Comms.h"


Comms::Comms(bool isMaster, uint16_t hz, DataHandler handlers[]){
  master = isMaster;
  pingDelay = 1/hz;
  dataHandlers = handlers; ######ERROR HERE######

  ////setup code////
  ...
Evan Weissburg
  • 1,564
  • 2
  • 17
  • 38
Ian
  • 26
  • 7
  • `DataHandler dataHandlers[];` is not a valid array declaration. A fixed-sized array must specify its size, expect in a function parameter, where the array syntax you are using is really just an alternative syntax for a pointer (`DataHandler handlers[]` and `DataHandler *handlers` are the same thing). So try using `DataHandler *dataHandlers;` instead, especially since an array decays into a pointer to its first element, so let `handlers` decay and you store the pointer. – Remy Lebeau Feb 08 '18 at 03:17
  • @RemyLebeau Ah that makes sense. Thankyou – Ian Feb 08 '18 at 04:05

1 Answers1

0

You have two options here:

  1. You can label dataHandlers/handlers/both as a DataHandler *.
  2. You can label the aforementioned variables as an std::vector<DataHandler>, with handlers being an lvalue (std::vector<DataHandler> &) reference.

The error I encountered when recreating the key aspect of your code was that stack-allocated arrays are basically immutable pointers, so you were basically writing the equivalent of DataHandler * const. Since all fields have a default initialization, whether or not you specified one in the initializer list in your constructor (you can't for the type you have for dataHandlers, as you essentially specified its default value in the field declaration), you were essentially attempting to reassign what your DataHandler pointer was pointing to.

  • This worked, however, your 2nd point may not work due to Arduino not being compatible with std and vectors. Thankyou! – Ian Feb 08 '18 at 04:03
  • You're welcome! In that case, then you might want to keep track of size since you're using your pointer as an array, or create your own implementation of the vector data structure. – frankmackey Feb 08 '18 at 04:05