Я давно не использовал C ++. Между тем, что я забыл, и тем, что со временем изменилось в C ++, я действительно бьюсь головой о стену, пытаясь сделать что-то, что было бы тривиально легко в JavaScript или любом другом языке, где функции - это объекты, а не просто простые указатели.
Мне кажется, я понимаю основную проблему c: функция-член класса существует только в одном месте в памяти (ее не существует для каждого экземпляра класса). Единственный способ, которым функция знает, что такое this, заключается в том, что указатель экземпляра передается в качестве невидимого первого аргумента каждому вызову функции. Обычный обратный вызов в стиле C не будет ничего знать о передаче этого указателя экземпляра.
Мне нужна новая функция, которая каким-то образом связана с моим экземпляром класса, та, которая знает, как передать «это» функции-члену. Это функция, которую мне нужно использовать в качестве обратного вызова.
Но я не знаю точно, как динамически создать такую функцию. Я думаю, что приведенный ниже код находится на правильном пути (за исключением приведения типов указателей), но это немного беспокоит меня, потому что кажется, что должно произойти некоторое динамическое выделение памяти c, и если так, какой-то способ отследить это распределение и выполнить очистку позже.
class SignalMonitor {
int dataPin;
unsigned short timings[RING_BUFFER_SIZE];
unsigned long lastSignalChange = 0;
int dataIndex = 0;
int syncCount = 0;
void signalHasChanged();
public:
SignalMonitor(int);
};
SignalMonitor::SignalMonitor(int dataPin) {
this->dataPin = dataPin;
function<void()> callback = bind(&SignalMonitor::signalHasChanged, this);
wiringPiISR(dataPin, INT_EDGE_BOTH, callback);
}
void SignalMonitor::signalHasChanged() {
unsigned long now = micros();
int duration = (int) min(now - this->lastSignalChange, 10000ul);
this->lastSignalChange = now;
cout << duration << '\n';
}
Мне кажется, это близко к тому, что я хочу, но я получаю эту ошибку:
acu-rite-433Mhz-reader.cpp:58:72: error: invalid cast from type ‘std::function<void()>’ to type ‘void*’
wiringPiISR(dataPin, INT_EDGE_BOTH, reinterpret_cast<void *>(callback));
^
Вот подпись вызова функции, к которой я пытаюсь передать этот обратный вызов:
int wiringPiISR (int pin, int edgeType, void (* function) (void))
Я обнаружил ряд похожих вопросов, которые обсуждались при поиске по этой теме c, но они либо не совсем соответствуют тому, что я пытаюсь сделать, либо предполагают гораздо большее знакомство с C ++, чем у меня есть в настоящее время. (Все, что я помню о типах указателей на функции, это то, что они очень быстро становятся адски безобразными!)
Я пытался использовать лямбда-функцию в качестве решения, но это привело к ошибке (помимо ошибки несоответствия типов) о чем-то Быть «временным», что, как я предполагаю, означало, что область действия лямбда-функции была временной.