как передать функцию void указателю void в C ++ - PullRequest
0 голосов
/ 13 февраля 2020

Вот моя проблема: у меня есть класс тактов, который используется для тактильных кнопок во встроенных приложениях.

Я добавил функцию setFunctions (), чтобы я мог связать 3 функции с каждым создаваемым мной экземпляром такта (который будет касаться коротких нажатий кнопок, отпусканий и длинных нажатий).

class tact
{
public:
tact(int assigned_pin, input_shift_register shift = {0,0,0}); // Constructor

void debounce();
short poll(bool debounce_flag);
void activate();
void setFunctions(void short_press_function(void), void release_press_function(void), void long_press_function(void));

short state;

private:
    int pin;
    void (*short_ptr)(void);
    void (*release_ptr)(void);
    void (*long_ptr)(void);
}

Поэтому я мог бы создать 3 уникальных функции в main для каждого нужного мне экземпляра такта и связать их с экземпляром такта с помощью члена setFunctions ().

Вот как член setFunctions работает (или должен). Он связывает 3 уникальные функции с 3 пустыми указателями, которые являются частью класса такта в private:

void tact::setFunctions(void short_press_function(), void release_press_function(), void long_press_function())
{
    short_ptr = short_press_function;
    release_ptr = release_press_function;
    long_ptr = long_press_function;
}

Затем указатели используются для доступа к функциям из члена активации (простой случай переключения, чтобы увидеть в каком состоянии кнопка такта в данный момент находится):

void tact::activate()
{
    switch (tact::state)
    {
    case SHORT_EFFECT_REQUIRED:
        short_ptr();
        break;

    case RELEASE_EFFECT_REQUIRED:
        release_ptr();
        break;

    case LONG_EFFECT_REQUIRED:
        long_ptr();
        break;

    default:
        break;
    }
    tact::state = 0;
}

В основном я планирую сделать это:

void up_short()
{
}
void up_release()
{
}
void up_long()
{ 
}

tact upPin(2);

void setup()
{
  upPin.setFunctions(up_short(), up_release(), up_long()); //ERRORS ARE HERE!!
}

 void loop()
 {
  //use the tact buttons in my applications!
  upPin.poll(DEBOUNCED); // Updates upPin.state

  if(upPin.state)  //if not 0, either pressed, released, or pressed long enough
    upPin.activate();
 }

, но setFunctions () в 3 раза упоминает одну и ту же ошибку:

argument of type "void" is incompatible with parameter of type "void (*)()"

одна ошибка для каждой из 3 функций, которые я передаю в качестве аргументов setFunctions ()

Итак, мой вопрос: что я делаю неправильно? Мне очень понравилось, как я мог просто использовать upPin.activate для доступа к своим функциям, и правильное действие выполняется автоматически ... Я не понимаю, почему setFunctions () не позволяет мне связывать void-функции с указателями на void-функции ???

Спасибо!

1 Ответ

2 голосов
/ 13 февраля 2020

Строка:

upPin.setFunctions(up_short(), up_release(), up_long())

вызывает функции up_short(), up_release() и up_long() каждая по отдельности. Эти функции возвращают void, который затем передается каждому параметру в setFunctions - вот почему вы сталкиваетесь с этой ошибкой 3 раза.

Что вы хотите сделать, это передать (указатели) функции сами на setFunctions

Если вы измените строку на:

upPin.setFunctions(up_short, up_release, up_long);

Вы должны увидеть эту работу

...