带/不带类的回调函数指针 C++ [英] Callback function pointers C++ with/without classes

查看:45
本文介绍了带/不带类的回调函数指针 C++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被卡住了.我试图形成一个函数,它会吃掉无类函数指针和对象中的指针.这是我当前的代码,希望能解释更多.

I got stuck. I am trying to form a function that will eat classless function pointers and ones from objects. Here is my current code that hopefully explains more.

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

(It should run on a Arduino, so I cannot use big libraries.)

首先,我将这个库用于 Arduino:

First off, I am using this library for the Arduino:

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

它接受在这种类型的设置定时器间隔内调用的函数:

Which takes functions which it calls on a set timer interval of this type:

typedef void (*timer_callback)(void);

据我所知,这是一个类函数,网页 指向成员函数的指针 让我走得很远,但还不够.可能是我这边的术语不足.

As far as my knowledge goes, it's a classles function, the webpage Pointers to member functions got me really far but, not far enough. Probably a terminology deficit on my side.

现在,我已经创建了自己的类,我想反过来使用这个 SimpleTimer 库.但是,如果我向 SimpleTimer 提供我的类函数,它就不喜欢它们(我的理解).但是如何在不改变 SimpleTimer 库的情况下实现这一点.

Now, I have made my own class which I would like in turn to use this SimpleTimer library. But if I feed the SimpleTimer my class functions, it does not like them (what I understand). But how would it be possible to make this happen without altering the SimpleTimer library.

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

So there is the class Robot, which has Robot::halt(). I want the robot to move forward for a set amount of time. Like so:

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);
}

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

The c_func variable is a classless function at this point, but I would like to use the Robot::halt function. I have looked, read, learned but haven't succeeded yet. I just can't seem to wrap my head around this one because I am missing some angle.

我试过了:

timer.setTimer(time, (this->*halt), 1);
timer.setTimer(time, Robot::*halt, 1);
timer.setTimer(time, &Robot::halt), 1);

但这都会导致同样的问题/我只是在黑暗中刺伤这里......

But it would all amount to the same problem/ me just stabbing in the dark here...

编辑

之前,我说过不想更改 SimpleTimer 库代码.我想在这个上卷土重来,我想改变它会有更好的选择.

Earlier, I said not wanting to change the SimpleTimer library code. I want to comeback on this one, I guess altering it there would be the better option.

感谢您提供的所有当前答案,我只允许将其中一个标记为可行的答案,实际上我在这里阅读的所有内容都非常有帮助.

Thanks for all the current answers already, I was only allowed to flag one as a viable answer, actually everyhting I read here was extremely helpful.

要继续此操作,请更改 SimpleTimer 代码.这个类需要引用包含我的暂停"功能的对象,对吗?因此,将 settimer 函数重载为将我的对象和我的函数作为两个单独指针的东西会起作用......?我想我已经掌握了这一点,但是,我还没有头脑.

To continue this, changing the SimpleTimer code. This class needs to have a reference to the object that holds my "halt" function, right? So, overloading the settimer function to something that takes my object and my function as two seperate pointers would work...? I think I am getting the hang of this but, I am not there yet with my head.

编辑

我不知道是谁又带来了这个,但是,任何找到这个线程的人.如果找到成员函数指针和最快的 C++ 委托很好的介绍了函数指针和成员函数指针.

I don't know who came with this one again but, anyone finding this thread. If found Member Function Pointers and the Fastest Possible C++ Delegates to give a very nice introduction in function pointers and member function pointers.

编辑

成功了,更改 SimpleTimer 库以使用此委托系统:http://www.codeproject.com/KB/cpp/FastDelegate.aspx

Got it working, changed the SimpleTimer library to use this Delegate system: http://www.codeproject.com/KB/cpp/FastDelegate.aspx

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

It integrated very nicely, and it could be nice to have a standard Delegate system like this in the Arduino library.

测试中的代码(工作)

类型定义

typedef FastDelegate0<> FuncDelegate;

机器人类代码:

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

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

void Robot::halt() {
    Serial.println("TEST");
}

SimpleTimer 类中的代码:

Code in SimpleTimer class:

int SimpleTimer::setTimerDelg(long d, FuncDelegate f, int n){
    f();
}

Arduino 在控制台中打印 TEST.

Arduino prints TEST in the console.

下一步把它放在一个数组中,不要看到那里有很多问题.谢谢大家,我简直不敢相信我在两天内学到的东西.

Next step putting it in an array, don't see a lot of problems there. Thanks everyone, I can't believe the stuff I learned in two days.

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

What's that smell? Is that the smell of...? Success!

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

For the ones interested, the used Delegate system does not amount to memory capacity issues: With 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

没有 FastDelegate:

Without 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

推荐答案

您可以通过制作 functor 对象,充当计时器代码和您的代码之间的代理.

You can do this by making a functor object, that acts as a proxy between the timer code and your code.

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

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

private:
    Robot &m_robot;
}

// ...

timer.setTimer(time, MyHaltStruct(*this), 1);

编辑

如果不能通过函子对象完成,您可以改为使用全局变量和函数,也许在命名空间中:

Edit

If it can't be done via a functor object, you could global variables and functions instead, maybe in a namespace:

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);

这仅在您有一个机器人实例时才有效.

This only works if you have one robot instance though.

这篇关于带/不带类的回调函数指针 C++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆