ISO C++ запрещает принимать адрес неквалифицированной или заключенной в скобки нестатической функции-члена для формирования указателя на функцию-член
Этот вопрос следует за этим вопросом
В последнем вопросе я узнал, как использовать список инициализаторов для решения моей проблемы, но работа с ros::Subscriber
требует другого решения.
В этом сценарии я имею дело с обратным вызовом. Если я оставлю обратный вызов как отдельную функцию, то программа запустится, но у меня нет доступа к членам класса и методам внутри функции, что противоречит цели. Вот мой автономный обратный вызов:
void setPRYCallback( const std_msgs::Empty& toggle_msg) {}
Как только я перемещаю это в свой класс, я сталкиваюсь с ошибкой.
шаги к внедрению в класс
// добавить переменную-член для
protected:
void setPRYCallback( const std_msgs::Empty& );
...
// ass метод
void ROSController::setPRYCallback( const std_msgs::Empty& toggle_msg) {}
...
// установить список инициализаторов
ROSController::ROSController() : sub("setPRY", &setPRYCallback )
Как мне предотвратить эту ошибку, сохраняя мой обратный вызов в качестве метода класса?
Программа с автономной функцией обратного вызова (программа запускается)
#include <ros.h> // https://github.com/ros-drivers/rosserial/blob/jade-devel/rosserial_arduino/src/ros_lib/ros.h
#include <std_msgs/Empty.h>
class ROSController {
protected:
ros::Subscriber<std_msgs::Empty> sub;
ros::NodeHandle _nh;
public:
void loop();
ROSController();
};
void setPRYCallback( const std_msgs::Empty& toggle_msg) {}
ROSController::ROSController() {
this->_nh.initNode();
this->_nh.subscribe(sub);
}
void ROSController::loop() {
this->_nh.spinOnce();
delay(1000);
}
Программа с обратным вызовом метода (сбой программы)
#include <ros.h> // https://github.com/ros-drivers/rosserial/blob/jade-devel/rosserial_arduino/src/ros_lib/ros.h
#include <std_msgs/Empty.h>
class ROSController {
protected:
ros::Subscriber<std_msgs::Empty> sub;
ros::NodeHandle _nh;
void setPRYCallback( const std_msgs::Empty& );
public:
void loop();
ROSController();
};
void ROSController::setPRYCallback( const std_msgs::Empty& toggle_msg) {}
ROSController::ROSController() : sub("setPRY", &setPRYCallback ) {
this->_nh.initNode();
this->_nh.subscribe(sub);
}
void ROSController::loop() {
this->_nh.spinOnce();
delay(1000);
}
arduino mega
@Jacksonkr, 👍2
Обсуждение2 ответа
Лучший ответ:
Когда вы перемещаете функцию setPRUCallback в свой класс, вы меняете прототип (ну, C++ меняет прототип) с:
void setPRYCallback( const std_msgs::Empty& toggle_msg) {}
Для:
void setPRYCallback( ROSController *this, const std_msgs::Empty& toggle_msg) {}
Теперь это не то, что ожидает функция регистрации обратного вызова, и поэтому она ломается.
Делая метод статическим,
он удаляет этот параметр *this, но также означает, что функция может получить доступ только к статическим данным внутри вашего класса (переменные также помечены
как статические
), и существует только одна копия функции (и статические
переменные), разделяемая между всеми экземплярами класса (возможно, не то, что вы хотите)..
Если вы определяете экземпляр как глобальное значение, как насчет того, чтобы установить обратный вызов с использованием лямбда-выражения в качестве переменной конструктора.
#include <ros.h>
#include <std_msgs/Empty.h>
class ROSController {
protected:
ros::Subscriber<std_msgs::Empty> sub;
ros::NodeHandle nh;
public:
ROSController(void (*staticPRYCallback)(const std_msgs::Empty& msg));
void begin();
void loop();
void setPRYCallback( const std_msgs::Empty& );
};
void ROSController::setPRYCallback(const std_msgs::Empty& toggle_msg) {}
ROSController::ROSController(void (*staticPRYCallback)(const std_msgs::Empty& msg))
: sub("setPRY", staticPRYCallback ) {
}
void ROSController::begin() {
nh.initNode();
nh.subscribe(sub);
}
void ROSController::loop() {
nh.spinOnce();
}
ROSController rosController([](const std_msgs::Empty& msg){
rosController.setPRYCallback(msg);
});
void setup() {
rosController.begin();
}
void loop() {
rosController.loop();
delay(1000);
}
Ссылка (пост моего блога на японском языке)
https://asukiaaa.blogspot.com/2020/09/define-cpp-callback-for-class-value-with-using-lambda-as-a-variable.html
- Как использовать SPI на Arduino?
- Подключение HX711 к трехпроводному датчику нагрузки
- Правильное использование * и & при передаче объектов в методах.
- Разница между массивом char и массивом unsigned char
- Печать содержимого файла SD - карты на ЖК-дисплее
- Отправка строки из RPi в Arduino - Рабочий код
- Сообщение об ошибке: "exit status 1 expected initializer before 'void'."
- Как передать нестатический член класса для обратного вызова на платформах avr?
Есть ли где-нибудь, где мы можем увидеть эту библиотеку "ros.h", которую вы используете?, @Majenko
Это сделает трюк: https://github.com/NimbRo/nimbro-op-ros/blob/master/src/nimbro/contrib/roscpp/include/ros/ros.h, @Jacksonkr
Начните с того, что сделайте "setPRYCallback" статическим., @Mikael Patel