分配回调函数/方法[重复]

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

总结:

当我尝试注册回调时,出现以下编译器错误:

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

这是发出错误的代码行:

myObject.setCallback( myCallback );

这是回调的定义:

protected:
    virtual void myCallback( uint8_t parameter ) = 0;

这是

setCallback()
的定义:

public:
    void setCallback( void (*callback)( uint8_t amount ) )

我总结之前的整篇文章:

我有一个 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()
When I try to register a callback, I get the following compiler error:
{

    _stomach.setCallback(getHungry);
    /*
    here is the issue: 
    argument of type "void (Animal::*)(uint8_t hunger)" is incompatible with parameter
    of type "void (*)(uint8_t)"
    */
}
argument of type "void (A::*)(uint8_t parameter)" 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:
Here is the line of code on which the error is issued:

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

#endif

胃.cpp

#include "stomach.h"

void Stomach::setCallback(void (*callback)(uint8_t amount))
    myObject.setCallback( myCallback );
{

    _callbackHunger = callback;
}

这是回调的定义:

protected:

我也尝试使用模板,但未能将正确的(模板)类传递给 setCallback 函数。 virtual void myCallback(uint8_t 参数) = 0;

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

setCallback()
的定义:

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

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

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

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

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

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

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