Dynamic function pointer (delegate)

Hi, I don't know if this is a the matter of the gcc, or Arduino. I feel the need to pass function pointer (delegate) of an object instace. (Passing function pointers as a parameter.) E.g. interrupt handling from libraries.

Unfortunately I can only pass static function pointers.

My suggestion is to allow function pointers of object instances. (And the compiler error message in other case is awful.)

Thanks, Balázs

Below is example code I use to pass a class definition as a delegate:

void PrintXmlTime(Print &pr,uint32_t t)
{
  char str[11];
  time_s ts;
  
      local_time(t,ts);
      //2008-10-31T15:07:38
      sprintf_P(str,PSTR("%04d-%02d-%02d"),ts.year+2000,ts.month+1,ts.day+1);
      pr.print(str);
      sprintf_P(str,PSTR("T%02d:%02d:%02d"),ts.hour,ts.minute,ts.second);
      pr.print(str);
}/*PrintXmlTime*/
  SdPrint Log;

  PrintXmlTime(Serial);
  PrintXmlTime(Log);

Serial is the reference to the standard hardware serial class and Log is a class reference to a data logger (SD card) class. Both of these classes define Print as a subclass and this allows me to use a single subroutine for writing to an SD card and printing to serial. This is all standard AVR C++.

Is this along the lines of what you're trying to do?

No. What I try to do is this:

class Rc5
{
  public:
    Rc5(int interrupt);
  private:
    void onInfraEvent();
}

Rc5::Rc5(int interrupt) {
  attachInterrupt(interrupt, this->onInfraEvent, CHANGE);
}

In this example the onIfraEvent() is my delegate function, which should be a member function. But the C compiler complains, so I had to do it this way:

class Rc5Class
{
  public:
    void init(int interrupt, int irDataPin);
  private:
    static void onInfraEvent();
}

Rc5Class::init(int interrupt) {
  attachInterrupt(interrupt, Rc5Class::onInfraEvent, CHANGE);
}
Rc5Class Rc5;

Where the onInfraEvent is a static function. So there can be only one Rc5 class instances, that can handle interrupts. :(

The attachInterrupt() function requires a simple pointer to a parameterless function returning void. A member function pointer on the other hand is a compound pointer that include a reference to "this" AND a reference to the function within "this". As such there is a parameter type conflict that triggers the compile error.

So much for understanding why, but I would agree with you that "this is what we want, so give us syntax to do so". For all I know this may already be possible (e.g. with some special typecast/dereference keyword), but I haven't seen any.

Member function pointers is a somewhat dark area when it comes to C++ in general. Part of the reason is that existing implementations were challenged (e.g. with backwards compatibility) when inheritance and later multiple inheritance was formally included in C++. If you're interested in the topic there is a decent article here:

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

If you want to propose changes/extensions to gcc however I think you're better off addressing this to the gcc community directly.

Okay. Now I understand that this is nothing to do with Arduino. So I go to other forums. I'll be back when I've got solution. Btw: I copy the error messages here for documentation reasons.

If I try to pass instance function I've got this:

argument of type 'void (Rc5::)()' does not match 'void (*)()'

If I try to cast "attachInterrupt(interrupt, (void (*)())(this->onInfraEvent), CHANGE);", I get this error message:

invalid use of member (did you forget the '&' ?)

If I put the "&" mark, I get this:

ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&Rc5::onInfraEvent'

I'm still not sure about this member function pointer stuff. I don't want member function pointer, I simply want function ponter of an instance.

I don't want member function pointer, I simply want function ponter of an instance.

A function pointer of an instance IS a member function pointer.