Class that uses a "in-sketch" defined callback function?

Hello.

I'm looking for advice about how to do the following task.

Let's pretend I have a class in my own written library that looks something like this(consider this as pseudo-code:

class actionButton
{
  _attachedPin;
  
  public:
  actionButton(byte attachToPin)
  {
    _attachedPin = attachToPin;
    pinMode(_attachedPin, INPUTPULLUP);
  }
  
  void checkForPress()
  {
    if(shortPress)
    {
      shortPressCallback();
    }
    else if(longPress)
    {
      longPressCallback();
    }
  }
}

The question I have is, how do I "send" a function pointer to the object of such a class which the object then would use for shortPressCallback() and longPressCallback()?

I figured this out a few years ago but that code project hit a brick-wall when I discovered that the Arduino core for the Due makes it impossible to attach a "in-sketch defined" function pointer to a external interrupt using the attachInterrupt() function inside of the objects class definiton(it had something to do with the Due's definiton of the attachInterrupt() function and it's 32-bit system, or something, I might have known too little to be able to work around it), I'm not sure if that is still true today but I can't find the code and I was hoping that there might be someone here whom right now has a firm understanding of how to do this in the simplest way possible(simple meaning straight forward from the perspective of writing the sketch and send the function pointer to the object of the relevant class).

I hope you all will have a nice day.

The question I have is, how do I "send" a function pointer

A function pointer is simply the address of a function. It's signature is void *someFunction(), because callback functions can not return values and can not take values.

Let's start off by:

 actionButton(byte attachToPin)
  {
    _attachedPin = attachToPin;
    pinMode(_attachedPin, INPUTPULLUP);
  }

is a BAD idea. If you now make a global object there is NO guarantee that code is executed because it's not in the code body. pinMode() might or might not already be define. That's why it's more common to have a begin() method.

And about the callback, that is a matter of function pointers :slight_smile:

class actionButton
{
  const byte _AttachedPin;
  void (*_shortPressCallback)();
  void (*_longPressCallback)();
  
  public:
  actionButton(byte p) : _AttachedPin(p)
  {
    
  }
  
  void begin()
  {
    pinMode(_AttachedPin, INPUT_PULLUP);
  }
  
  void setShortPressCallback(void (*p)()){
    _shortPressCallback = p;
  }
  
  void setLongPressCallback(void (*p)()){
    _longPressCallback = p;
  }
  
  void checkForPress()
  {
    if(true)
    {
      _shortPressCallback();
    }
    else if(false)
    {
      _longPressCallback();
    }
  }
};