Начал я тут облагораживать проигрывалку MIDI файлов немножко.
В частности, мне не нравилось, как я сделал реализацию callback-функций, которые вызываются библиотекой. (Сделано было на скорую руку, «чтобы заработало», да так и оставлено.)
И начал я изучать вопрос на тему «есть ли в 2025 году стандартные способы указывать в качестве сишной callback-функции функцию-член класса».
И напоролся на интересную статью, в которой приведён пример (см. рис. 1), который синтактически неправильный для того C++, который я помню. 🙂
Оказывается, пока меня не было, они там в C++ насовали всякого нового (в версию C++ 11). И тот пример из статьи использует это самое новое.
Вот ведь… Придётся разбираться.

(Да, я в курсе, что C++11 «новый» только для меня, а нормальные программисты уже могут не помнить, что когда-то было как-то иначе.)
Мне больше нарвится использование стандартного шаблона std::function который представляет нечто, что может вызываться как функция — это может быть и указатель на функцию, и объект-функция, и лямбда-выражение
В использовании что то вроде:
#include#include
void print_num(int i)
{
std::cout << i << '\n';
}
int main()
{
std::function f_display = print_num;
std::function f_display_42 = []() { print_num(42); };
std::function f_display_31337 = std::bind(print_num, 31337);
f_display(-9);
f_display_42();
f_display_31337()
}
Вывод
-942
31337
Эм что то веь код покорежило и инклуды пропали, там должны быть
#include
#include
да блин
#include «functional»
#include «iostream»
только в угловых скобках, дфижок сайта почему то наглухо вырезает все, что в них даже если они внутри блока кода находятся.
А если callback должен принимать указатель на данные?
void my_callback(char * my_data);
как вызвать член класса, который этот указатель примет?
(Эти все штуки тоже появились после того, как я «на минуточку отошел» от программирования, поэтому спрашиваю.)
Вот таким образом, главное правильно забиндить функцию
#include "iostream"
#include "functional"
#include "stdio.h"
struct Foo
{
void print(char * buff) {
// что то делаем
printf("%s", buff);
}
};
int main() {
char buff[] = "Какие то данные ";
//в Си массив это и так указатель можно без этого
char * buff_ptr = buff;
//обьявление экземпляра класса
const Foo foo;
// просто чтобы в bind вместо std::placeholders::_1 писать просто _1
using std::placeholders::_1;
// биндим функцию конкретного экземпляра класса
// Первый параметр функция которую биндим,
// вторая экземпляр класса функция которого будет вызываться (или ссылка на него)
// третий и далее параметры которые будем передавать функции
// можно как передавать параметры создаваемой функции так и статически заданные значения
// параметры функции f_display2 которую мы создаем будут называться _1, _2 и.т.д.
std::function f_display2 = std::bind(&Foo::print, foo, _1);
f_display2(buff_ptr);
return 0;
}
Опять вся разметка слетела 🙁 но думаю разберетесь.
Блин оно опять посчитало все внутри угловых скобок тегом и снесло может так
Вот как обьявление функции должно быть
std::function < void(char *) > f_display2 = std::bind(&Foo::print, foo, _1);
Спасибо! А то времени на самостоятельное раскуривание всех этих нововведений у меня не предвидится. А тут вот вы помогли. 🙂
Надо будет разобраться.
Доброе утро.
А какой метод крепления плат датчиков на деку в результате оказался лучшим: на термоклей или на герметик?
А то мне платы для «активной» клавиатуры тоже придётся на деку устанавливать. Пока склоняюсь к варианту термоклея, т.к. не исключено что первый вариант плат потребует доработки и их надо будет снять. С термоклеем хотя бы понятно, как это можно будет сделать.