указатели — конструкторы класса c ++ автоматически отображают объекты в обработчик событий

В настоящее время я работаю над небольшим проектом для моего биглебона. По сути, цель состоит в том, чтобы создать фреймворк, который дает полную мощь c ++ в отличие от стандартного фреймворка javaScript beaglebone, но также прост в использовании для разработчика, как и фреймворк arduino.

Одна из вещей, которые я создал, — это готовые классы для различных типов простых прерываний GPIO, таких как кнопки, поворотные энкодеры и т. Д., Поэтому разработчик просто должен определить кнопку и сообщить ей, какой вывод GPIO подключен к beaglebone.

Прямо сейчас мне нужно вручную добавить функцию pollInterupt () объекта прерывания в основной цикл, чтобы программа могла многократно проверять состояние вывода GPIO inerupts.

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

Кажется, я бью кирпичную стену. Попытка сделать фреймворк простым для конечного пользователя означает, что код за сценой становится глупо сложным. Лучший способ автоматически обработать определенные объекты прерываний — это список ссылок. Вот как выглядит код прототипа в данный момент.

#include <iostream>

class interuptButton;
class interuptHandler;

class interuptHandler{
public:
class node{
public:
node *next;
node *prev;
public:
void *interupt;
};

node *first;
node *last;
node *current;
node *temp;

public:
interuptHandler(){
first = new node;
last  = new node;
first -> prev = NULL;
first -> next = last;
last  -> prev = first;
last  -> next = NULL;
}
void add(void *_interupt){
temp = new node;

current = last -> prev;
current -> next = temp;
temp    -> prev = current;
temp    -> next = last;
last    -> prev = temp;

temp    -> interupt = _interupt;
}
void run(){
current = first -> next;
while(current -> next != NULL){
std::cout << current -> interupt << std::endl;
//              std::cout << current -> interupt -> pin << std::endl;
//              current->interupt->pollInterupt();
//              std::cout << reinterpret_cast < interuptButton* > (current->interupt)->pin << std::endl;
current = current -> next;
}
}
}handler;class interuptButton{
public:
int  pin;
bool value;
public:
interuptButton(int _pin){
pin = _pin;
handler.add(this);
}
void pollInterupt(){
std::cout << "check pin " << pin << " to see if the GPIO has changed" << std::endl;
}
};int main(int argc, char **argv){

interuptButton buttonA(41);
interuptButton buttonB(45);
interuptButton buttonC(43);

handler.run();

return 0;
}

Кажется, что система работает, и конструктор interuptButton успешно передает вновь созданные объекты в список ссылок interuptHandler, который затем может распечатать адрес памяти в функции run () с выходными данными:

bin/./test
0x7fff5fbff9e0
0x7fff5fbff9d0
0x7fff5fbff9c0

Проблема в том, что когда я раскомментирую любую из других строк в run (), где я пытаюсь получить доступ к переменным или функциям объекта указателя, g ++ начинает выдавать ошибки.

Возвращаются первые две строки:

src/main.cpp: In member function ‘void interuptHandler::run()’:
src/main.cpp:47: error: ‘void*’ is not a pointer-to-object type
make: *** [all] Error 1

и третья строка возвращает:

src/main.cpp:49: error: invalid use of incomplete type ‘struct interuptButton’
src/main.cpp:4: error: forward declaration of ‘struct interuptButton’
make: *** [all] Error 1

Любой совет о том, как получить доступ к переменным и функциям этих объектов через их указатели, будет очень полезен.

Еще лучше, если у кого-то есть лучший способ автоматически отправлять объекты в обработчик событий за сценой, я весь в ушах.

1

Решение

в node структура, interrupt указатель является указателем на void Это означает, что он может указывать на любой тип. Тем не менее, компилятор не знает, на что он указывает, поэтому вы должны сообщить компилятору, какого типа он действительно указывает на использование Typecasting:

reinterpret_cast<interuptButton*>(current->interrupt)->pollInterrupt();

Что касается другой проблемы, у вас есть круговая зависимость. Класс interruptHandler зависит от класса interruptButton и наоборот. Это вы должны решить, разделив определение и реализацию одного или обоих классов. Простейшим способом было бы просто поставить interruptButton определение класса над interruptHandler определение и поместите реализацию, то есть фактический код interruptButton после interruptHandler определение класса.


Если вы хотите использовать несколько прерываемых классов, не только interruptButton класс, вы должны использовать наследование и абстрактные базовые классы с виртуальными функциями. Тогда вам не понадобится void указатель или приведение типа:

struct baseIntertuptable
{
virtual void pollInterrupt() = 0;
};

struct interruptHandler
{
private:
struct node
{
// ...
baseInterruptable* interrupt;
};

public:
void run()
{
// ...
current->interrupt->pollInterrupt();
// ...
}
};

class interruptButton : public baseInterruptable
{
public:
void pollInterrupt()
{
// ...
}
};

Это также должно решить вашу проблему с круговыми зависимостями определений классов, как абстрактный базовый класс baseInterruptable теперь полностью определен, прежде чем его использовать и interruptHandler класс использует только это.

0

Другие решения

Вам нужно начать перемещение определений функций в файлы .cpp? Похоже, у вас есть доступ к внутренним элементам interuptbutton до его определения.

Или, так как это всего 1 большой файл .cpp, вы можете определить run функционировать перед главным чтобы исправить ваш второй набор ошибок.

Первая ошибка говорит сама за себя, может быть, вы должны сделать Интерфейс прерывания и держать указатели на него, а не на void*? reinterpret_castОн просто делает все так безобразно.

class IInterupt{
// other stuff common to all interupt classes
void pollInterupt() = 0; // pure virtual force all inheriting classes to implement.
}

class interuptButton : public IInterupt{ //bla bla }

class node{
public:
node *next;
node *prev;
public:
IInterupt*interupt;
};
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector