带有/不带类的回调函数指针C++

Adu*_*uen 12 c++ pointers class arduino callback

我被困.我正在尝试形成一个函数,它将吃掉无类函数指针和来自对象的函数.这是我目前的代码,希望能够解释更多.

(它应该在Arduino上运行,所以我不能使用大型库.)

首先,我使用这个库为Arduino:

/* SimpleTimer - A timer library for Arduino.
 * Author: mromani@ottotecnica.com
 * Copyright (c) 2010 OTTOTECNICA Italy
 */
Run Code Online (Sandbox Code Playgroud)

它采用它在此类型的设定计时器间隔上调用的函数:

typedef void (*timer_callback)(void);
Run Code Online (Sandbox Code Playgroud)

据我所知,它是一个类别功能,成员函数的网页指针让我真的很远,但还不够远.可能是我这方面的术语缺陷.

现在,我已经创建了自己的类,我想依次使用这个SimpleTimer库.但是,如果我为SimpleTimer提供我的类函数,它就不喜欢它们(我理解).但是如何在不改变SimpleTimer库的情况下实现这一目标是可能的.

所以有类机器人,它有Robot::halt().我希望机器人能够向前移动一段时间.像这样:

void Robot::forward(int speed, long time) {
    reset();
    timer.setTimer(time, c_func, 1);

    analogWrite(l_a, speed);
    analogWrite(r_a, speed);
    isMoving(true);
}

void Robot::halt() {
    __isMoving = false;
    digitalWrite(r_a, LOW);
    digitalWrite(r_b, LOW);
    digitalWrite(l_b, LOW);
    digitalWrite(l_a, LOW);
}
Run Code Online (Sandbox Code Playgroud)

此时c_func变量是一个无类函数,但我想使用该Robot::halt函数.我看了,读过,学过但还没有成功.我似乎无法绕过这一个,因为我错过了一些角度.

我试过了:

timer.setTimer(time, (this->*halt), 1);
timer.setTimer(time, Robot::*halt, 1);
timer.setTimer(time, &Robot::halt), 1);
Run Code Online (Sandbox Code Playgroud)

但这一切都等于同样的问题/我只是在黑暗中刺伤......

编辑

早些时候,我说不想改变SimpleTimer库代码.我想回归这个,我想改变它会有更好的选择.

感谢所有当前的答案,我只被允许标记为一个可行的答案,实际上我在这里读到的每一个都非常有帮助.

要继续此操作,请更改SimpleTimer代码.这个类需要引用一个持有"halt"函数的对象,对吧?所以,将settimer函数重载为将我的对象和我的函数作为两个单独的指针的东西可以工作......?我想我已经掌握了这一点但是,我还没有我的头脑.

编辑

我不知道是谁再次来到这个,但是,任何人都找到了这个帖子.如果找到成员函数指针和最快可能的C++委托给函数指针和成员函数指针一个非常好的介绍.

编辑

搞定了,改变了SimpleTimer库以使用这个Delegate系统:http: //www.codeproject.com/KB/cpp/FastDelegate.aspx

它集成得非常好,在Arduino库中有一个像这样的标准Delegate系统可能会很好.

代码与测试(工作)

的typedef

typedef FastDelegate0<> FuncDelegate;
Run Code Online (Sandbox Code Playgroud)

机器人类中的代码:

void Robot::test(){
    FuncDelegate f_delegate;
    f_delegate = MakeDelegate(this, &Robot::halt);

    timer.setTimerDelg(1, f_delegate, 1);
}

void Robot::halt() {
    Serial.println("TEST");
}
Run Code Online (Sandbox Code Playgroud)

SimpleTimer类中的代码:

int SimpleTimer::setTimerDelg(long d, FuncDelegate f, int n){
    f();
}
Run Code Online (Sandbox Code Playgroud)

Arduino在控制台中打印TEST.

下一步将它放在一个数组中,不要看到很多问题.谢谢大家,我无法相信我在两天内学到的东西.

那是什么味道?这是......的味道吗?成功!

对于感兴趣的人,使用的Delegate系统不等于内存容量问题:使用FastDelegate

AVR Memory Usage
----------------
Device: atmega2560

Program:   17178 bytes (6.6% Full)
(.text + .data + .bootloader)

Data:       1292 bytes (15.8% Full)
(.data + .bss + .noinit)


Finished building: sizedummy
Run Code Online (Sandbox Code Playgroud)

没有FastDelegate:

AVR Memory Usage
----------------
Device: atmega2560

Program:   17030 bytes (6.5% Full)
(.text + .data + .bootloader)

Data:       1292 bytes (15.8% Full)
(.data + .bss + .noinit)


Finished building: sizedummy
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 8

您可以通过创建一个functor对象来完成此操作,该对象充当计时器代码和代码之间的代理.

class MyHaltStruct
{
public:
    MyHaltStruct(Robot &robot)
        : m_robot(robot)
        { }

    void operator()()
        { robot.halt(); }

private:
    Robot &m_robot;
}

// ...

timer.setTimer(time, MyHaltStruct(*this), 1);
Run Code Online (Sandbox Code Playgroud)

编辑

如果无法通过仿函数对象完成,则可以使用全局变量和函数,也可以在命名空间中:

namespace my_robot_halter
{
    Robot *robot = 0;

    void halt()
    {
        if (robot)
            robot->halt();
    }
}

// ...

my_robot_halter::robot = this;
timer.setTimer(time, my_robot_halter::halt, 1);
Run Code Online (Sandbox Code Playgroud)

这只适用于您有一个机器人实例的情况.

  • 你_could_这样做,如果setTimer是一个模板和接受的仿函数.看起来它真的只接受`void(*timer_callback)()`给我:http://arduino.cc/playground/Code/SimpleTimer#GetTheCode (2认同)