在 (Arduino) c++ 中分配带有继承的回调函数/方法

问题描述 投票:0回答:1

我有一个 Arduino 项目。每只动物都有胃。它想告诉动物,我应该饿了。所以我要使用一个回调,这是我从其他语言中知道的。当我想在动物中使用回调来传递虚拟方法(然后被覆盖)时,我遇到了无效类型问题。

动物.h

#ifndef animal_h
#define animal_h

#include <Arduino.h>
#include <stomach.h>

class Animal
{
public:
    Animal();

protected:
    virtual void getHungry(uint8_t hunger) =0;

private:
    Stomach _stomach;
};

#endif

动物.cpp

#include "animal.h"

Animal::Animal()
{
    _stomach.setCallback(getHungry);
    /*
    here is the issue: 
    argument of type "void (Animal::*)(uint8_t hunger)" is incompatible with parameter
    of type "void (*)(uint8_t)"
    */
}

胃.h

#ifndef stomach_h
#define stomach_h

#include <Arduino.h>

class Stomach
{
public:
    void setCallback(void (*)(uint8_t));

private:
    void (*_callbackHunger)(uint8_t amount) = nullptr;
};

#endif

胃.cpp

#include "stomach.h"

void Stomach::setCallback(void (*callback)(uint8_t amount))
{
    _callbackHunger = callback;
}

我也尝试过使用模板,但未能将正确的(模板)类传递给 setCallback 函数。

问题出在动物构造函数中。 _stomach.setCallback(gethungry) 在我的 IDE 中显示错误:

“void (Animal::)(uint8_t饥饿)”类型的参数与“void ()(uint8_t)”类型的参数不兼容

c++ arduino callback arduino-c++
1个回答
-1
投票

您确实应该编辑您的问题并将其减少为一段,也许两段。

错误告诉您预期的回调只是一个普通函数,但提供的回调是一个成员方法。

C++ 中的方法有一个隐藏参数,即

this
指针。因此,您不能只在需要函数的地方传递方法,因为调用者没有
this
指针可提供给方法调用。

您可以通过多种方式解决此问题:

  1. 使您的回调
    static
    ,并让它接受
    void* userData
    参数。使注册函数不仅接受回调,还接受用户数据指针。当调用注册的回调时,还要向其传递注册的用户数据指针。然后,回调将用户数据指针转换为注册者的实例,并调用注册者的方法,如下所示:
    static void myStaticCallBack( void* userData )
    {
        ((MyClass*)userData)->myMemberCallback();
    }
  1. 利用 lambda,它自版本 11(2011 年发布)以来就存在于 C++ 中。它们使一切变得更容易。在这里阅读它们:https://en.cppreference.com/w/cpp/language/lambda
© www.soinside.com 2019 - 2024. All rights reserved.