Funktionspointer auf nicht statische Methode

Im "zeigt her eure geilen Projekte" habe ich mein i2cKeylib vorgestellt.
Bei der hatte ich jetzt das Problem das ich in einer Klasse eine Interruptserviceroutine
brauchte.
attachInterrupt nimmt aber aus C++ Gründen keine Pointer auf dynamische Klassenmethoden an.
Ich habe mir geholfen in dem ich 2 statische Methoden gebaut habe die über gespeicherte
This-Pointer auf die Elemente der Klasse zugreifen konnten.

Ich finde das nicht sehr elegant. Für diesen Zweck zwar ausreichend aber nicht schön.
Hat jemand schlauere Ideen ?

Ulli

Du kannst die statische Methode auch direkt zur ISR machen.
Das erlöst dich aber nicht von dem "this", wenn dir eine komplett statische Klasse nicht weiter hilft.

Die einzige Chance, die ich sehe, ist das Objekt als Singleton auszubilden.
Das orientiert sich dann wenigstens halbwegs an den üblichen "OOP Design Pattern"
Mal abgesehen davon, dass Singletons böse sind.

Mal abgesehen davon, dass Singletons böse sind.

Objekte in der Arduino-Welt sind öfters mal Singletons oder sollten/könnten welche sein.
(Wire, EEPROM, RTC, in der Praxis auch Displays oder Keypads, usw.)

ISR sind auch böse, oder aber zumindest dumm, da sie keine Aufrufparameter haben.
Brauchst also pro Instanz eine eigene ISR, oder der aktuelle Auslöser der ISR ist dir egal.
Auf jeden Fall macht es nicht viel Sinn, eine nicht-statische Methode als ISR verwenden zu wollen, da Methoden nur einmal existieren und du keine Chance hast, einer ISR Parameter, z.B. den this-Zeiger, mitzugeben.

Du hast natürlich Recht. Selbst wenn es mir gelungen wäre eine non Static als ISR zu nehmen hätte
sie im Aufrufmoment gar nicht "gewusst" zu welcher Inkarnation sie eigentlich gehört.

Ulli

Man kann eine Lambda Funktion verwenden und ausnutzen dass Lambas ohne Capture Liste direkt in Funktionszeiger (auf void, void) umgewandelt werden können. Das macht die Syntax schöner da die Wrapper Methode entfällt, aber ist letztlich das gleiche:

class OtherClass    //Test Klasse die eine Methode mit Callback-Parameter enthält
{
public:
  void setFunction(void(*callBack)(void))    //Callback setzen
  {
    func = callBack;
  }

  void callFunction()     //Callback-Funktion aufrufen. Das wäre normale private und intern. Nur zum Test hier
  {
    Serial.println("callback");
    if (func != NULL)
      func();
  }
private:
  void(*func)(void);    //Zeiger auf Callback
};

class MyClass   //eigene Klasse die den Callback auf eine ihre Methoden setzen soll
{
public:
  MyClass()
  {
    static MyClass* obj = this;

    otherClass.setFunction(
      []() { obj->doSomething(); }
    );
    otherClass.callFunction();  //Callback testweise auslösen damit man sieht dass es geht
  }

  void doSomething()
  {
    Serial.println("do something");
  }

private:
  OtherClass otherClass;
};

void setup()
{
  Serial.begin(9600);

  MyClass myClass;
}

void loop()
{
}

Es gibt nun mal einen Unterschied zwischen Zeigern auf Funktionen und Zeigern auf Methoden. Und ohne Umwege und Nachteile kommt man da nicht drum herum.

Es gibt Anwendung wo das ok ist. Singeltons mögen nicht gut sein, aber im Arduino Bereich kommen sie oft vor. z.B. ein LCD oder ein Key Pad. Wenn man aber mehrere Objekte der Klasse hat geht das natürlich nicht.

Na ja und ich wollte in meiner Lib eben die Möglichkeit schaffen eventuell auch mehr als eine
Tastatur anzuschließen.

Ulli