C ++如何在类中调用方法作为TaskScheduler的函数指针 - Arduino

时间:2018-05-08 13:17:45

标签: c++ arduino taskscheduler

我尝试实现在C ++类中调用的任务,它需要一个回调函数。因为我对C ++很陌生,虽然我对指针有一个粗略的理解,但这是我无法弄清楚的:

我正在使用TaskScheduler 要设置课程中所需的所有内容,我想调用以下函数 arduino的常规示例不使用类,我正在努力使其在我的重构代码中工作。

void Weather::setup(std::shared_ptr<Scheduler> s ,int id, String appid, uint32_t interval) 
{
  ...
  weatherTask(interval, TASK_FOREVER, &Weather::updateWeatherCallback, *scheduler, true);
}

updateWeatherCallback-function也在这个类中实现:

void Weather::updateWeatherCallback() {...}

除了使用上面的代码之外,我在Stackoverflow上尝试了一些lambda Variants,并简单地介绍了以下内容:

weatherTask(interval,TASK_FOREVER, [this](){this->updateWeatherCallback;},*scheduler,true);

但我认为我对Stackoverflow上的这些答案的理解并不好 - 更多的试验和错误 - 这使得搜索“正确的答案”变得困难

TaskScheduler-Library中的一些细节:

typedef void (*TaskCallback)();
class Task {
  friend class Scheduler;
  public:
    INLINE Task(unsigned long aInterval=0, long aIterations=0, TaskCallback aCallback=NULL, 
       Scheduler* aScheduler=NULL, bool aEnable=false, TaskOnEnable aOnEnable=NULL, 
       TaskOnDisable aOnDisable=NULL);
...

谢谢:)

3 个答案:

答案 0 :(得分:0)

希望这会有所帮助。 Programs as Data: Function Pointers

在您的示例中,您可以按如下方式声明天气等级,

class Weather {
   public:
      setup(std::shared_ptr<Scheduler> scheduler, int id, String appid, uint32_t interval);
      updateWeatherTask(uint32_t interval, <Your Const>, function callback_func, std::shared_ptr<Scheduler> scheduler, bool someVar);
}

每当您声明方法体时,尝试使用相关参数调用callback_func函数内的updateWeatherTask函数。

<强>更新

这只是一种方法。请参阅您可以找到不同简单方法的链接。

答案 1 :(得分:0)

虽然使用上面的函数指针是旧方法,但更新的方法是使用函数对象和<functional>库。有关整个图书馆的概述,请参阅herestd::function中的the examples表示“这就是它的工作原理”教程。

还要考虑lambdas这类事情。这也非常有用,也可以存储在std::function内。

答案 2 :(得分:0)

weatherTask想要一个函数指针,而不是指向成员的指针。解决此问题的一种可能方法是创建一个辅助结构并将该函数绑定到std::function

#include <functional>

template <typename T>
struct Callback;

template <typename Ret, typename... Params>
struct Callback<Ret(Params...)> {
   template <typename... Args> 
   static Ret callback(Args... args) {                    
      func(args...);  
   }
   static std::function<Ret(Params...)> func; 
};

template <typename Ret, typename... Params>
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;

创建weatherTask时,使用以下命令将成员函数绑定到回调:

Callback<void(void)>::func = std::bind(&Weather::updateWeatherCallback, this);
TaskCallback func = static_cast<TaskCallback>(Callback<void(void)>::callback);
weatherTask(interval, TASK_FOREVER, func, *scheduler, true);

该解决方案是this问题的回答。由于我不能发表评论,我决定将此作为答案。

或者你可以使用类似蹦床的功能。因此,您需要存储指向Weather对象的全局指针。

Weather global_ptr;

然后您就可以使用lambda函数创建weatherTask

weatherTask(interval, TASK_FOREVER, [](){global_ptr->updateWeatherCallback();}, *scheduler, true);