0
Class A {
public:
  A();
  void onTouch();
}

A::A() {
  touchAttachInterrupt(1, std::bind(&A::onTouch, this), 40)
}

This does not works for me with ESP32. The definition of the touchAttachInterrupt is:

void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold);

My code results in a compilation error,

error: cannot convert 'std::_Bind_helper<false, void (TouchPin::*)(), TouchPin*&>::type' {aka 'std::_Bind<void (TouchPin::*(TouchPin*))()>'} to 'void (*)()
Priyank Bolia
  • 14,077
  • 14
  • 61
  • 82

1 Answers1

0

It looks like touchAttachInterrupt() only accepts a simple function pointer, nothing else. You can't pass it function objects. If you wish to retain the link between the callback method and the object that owns it, you have to do it manually. It's all C down there in ESP IDF anyway - any convenient C++ functionality will not work unless it remains in C++ land.

Some nicer C callback APIs in ESP IDF allow you to pass a single user argument together with the function pointer, which gets passed back to you when the callback is invoked. That argument could be used to resolve the object pointer. Unfortunately this is not the case in this API. Arduino does tend to simplify its interfaces at the cost of such useful little hooks.

So you're pretty much stuck with the "good old" singleton pattern.

Class A {
public:
  A();
  void onTouch();
  static void touchCallback() {
    if (myself) {
      myself->onTouch();
    }
  }
protected:
  A* myself {nullptr};
}

A::A() {
  assert(A::myself == nullptr);
  A::myself = self;
  touchAttachInterrupt(1, A::touchCallback, 40);
}
Tarmo
  • 3,728
  • 1
  • 8
  • 25
  • There are multiple pins, a singleton won't work for my use case. – Priyank Bolia Oct 25 '22 at 05:59
  • Then you need to attach a different callback function to each pin. There is no way to pass extra information through the callback in this API you've described. – Tarmo Oct 25 '22 at 08:32