Passing a method pointer
The easiest method I know to do this would be to use a &quot;C&quot;-style wrapper for the member function call. This is in fact done to interface C callbacks with C++ objects.
You could do it like this:
struct Blinky {
  //state etc.
  bool isOn() { return /* something useful */ true; }
};

// The &quot;C&quot; wrapper for the callback
bool Blinky_callback(void *vblinky)
{
  return static_cast&lt;Blinky*&gt;(vblinky)-&gt;isOn();
}

struct MyClass {
  void add_callback(void *obj, bool (*callback_method)(void *), byte behaviour) {
    // ...
    bool result = callback_method(obj);
    // ...
  }
};

// Globals
MyClass c;
Blinky b;

void setup() {
  c.add_callback(&amp;b, Blinky_callback, 0);
}

A slightly tidier way with a static member (functionally identical):
struct Blinky {
  //state etc.
  bool isOn() { return /* something useful */ true; }

  static bool callback(void *vblinky) {
    return static_cast&lt;Blinky*&gt;(vblinky)-&gt;isOn();
  }
};

// ...
c.add_callback(&amp;b, Blinky::callback, 0);

Other variants would be using inheritance and virtual functions.
// Abstract base class
struct Sensor {
  virtual bool do_check() = 0;
};

struct Blinky : public Sensor {
  bool do_check() override { return true; }
}

Then you can have your add_callback look like:
void MyClass::add_sensor(Sensor *sensor) {
  // ...
  bool result = sensor-&gt;do_check();
  // ...
}

This is relatively nice to code with, and the compiler has a fighting chance at keeping your code typesafe, if all the &quot;things&quot; you want to control can conform to the same interface. The virtual dispatch won't cost much more (if anything) than the static wrapper in the previous example. You &quot;pay&quot; a few bytes per class and one pointer per instance for the virtual table though.
More modern techniques would involve templates and/or lambdas, or perhaps std::function, but all that seems overkill if your need is as described (and might generate a lot more code than you're expecting, or do dynamic allocations for std::function which is best avoided in context).

Remark: if you want to do it with (non-static) member function pointers, it is possible but the syntax is hairy:
void add_callback(Blinky *obj, bool (Blinky::*callback_method)(), byte behaviour) {
  // ...
  bool result = (obj-&gt;*callback_method)();
  // ...
}

And you're tied to that class. Unless you make add_callback a template, but beware extra codegen.