Я пишу программу на C ++, которая использует библиотеку C. Эта библиотека берет указатели на функции для обратных вызовов, и я хочу, чтобы она вызывала методы экземпляра. К счастью, библиотека принимает дополнительный параметр данных, который является просто «void *» и передается без изменений в обратный вызов. Итак, я создал обобщенную c функцию-оболочку обратного вызова.
void callbackWrapper(std::function<void ()> &func) {
func();
}
Теперь, когда мне нужно зарегистрировать обратный вызов в библиотеке, я передаю указатель на функцию callbackWrapper в качестве вызываемой функции, и указатель на функцию std :: как дополнительный параметр данных. Когда происходит обратный вызов, он вызывает мою оболочку, которая затем вызывает фактический метод / лямбда / то, что я действительно хотел вызвать.
Но в приведенном выше коде есть ошибка. Я использовал «&» вместо «*», что означает, что функция ожидает ссылку на std :: function, а не указатель. Функция должна была определена так:
void callbackWrapper(std::function<void ()> *func) {
(*func)();
}
Я давно не замечал ошибку - потому что она работала отлично. Я только заметил, потому что я выслеживал несвязанную ошибку, и просто случайно увидел ее. Итак, мой вопрос, почему? У меня есть три возможных ответа:
- Стандарт C ++ позволяет автоматизировать c продвижение указателей на ссылки в этом случае.
- Мой компилятор (g cc 9.3.1) заметил несоответствие и тихо исправил его для меня.
- Адрес указателя просто оказался в нужном месте в кадре стека, что вызов может быть успешным.
Любые мои теории верны? Если нет, что случилось?