回调函数指针C ++有/无类 [英] Callback function pointers C++ with/without classes

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

问题描述

我被困。我试图形成一个功能,将吃从对象无类函数指针及的。这是我目前的code,它希望详细解释。

(它应该在Arduino的运行,所以我不能用大库)。

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

  / * SimpleTimer  - 定时器库的Arduino。
 *作者:mromani@ottotecnica.com
 *版权所有(C)2010 OTTOTECNICA意大利
 * /

这需要它这种类型的一组定时器间隔调用功能:

 无效的typedef(* timer_callback)(无效);

据我所知所说,这是一个classles功能,网页的指针成员函数 的让我真的很远,但远远不够。也许在我身边一个术语赤字。

现在,我已经作出了自己的阶级,我想反过来使用这种SimpleTimer库。但是,如果我喂SimpleTimer我的类函数,它不喜欢他们(我的理解)。但是,如何将有可能做到这一点不改变SimpleTimer库。

因此​​,有类机器人,它具有机器人::停止()。我想机器人向前移动的时间设定量。像这样:

 无效机器人::前进(INT速度,时间长){
    重置();
    timer.setTimer(时间,c_func,1);    analogWrite(l_a,速度);
    analogWrite(R_A,速度);
    isMoving(真);
}无效机器人::停止(){
    __isMoving = FALSE;
    digitalWrite(R_A,LOW);
    digitalWrite(r_b,LOW);
    digitalWrite(l_b,LOW);
    digitalWrite(l_a,LOW);
}

该c_func变量是在这一点上阶级的功能,但我想使用机器人::停止功能。我已经看过,阅读,学会了,但还没有成功。我好像不能换行我的头周围的这一个,因为我错过了一些角度。

我试过:

  timer.setTimer(时间,(这个 - > *停止),1);
timer.setTimer(时间,机器人:: *停止,1);
timer.setTimer(时间,和放大器;机器人::停止),1);

但是,如果所有的量相同的问题/我只是在黑暗中刺伤这里...

修改

此前,我说不想改变SimpleTimer库code。我想在此一复出,我想改变它会有更好的选择。

感谢所有已经是目前的答案,我只被允许标志一个作为一个可行的答案,其实我everyhting读到这里是非常有帮助的。

要继续这样,改变了SimpleTimer code。这个类需要有保存我的叫停函数的对象,合适的参考?所以,超载SetTimer函数的东西,把我的对象,我作为两个单独的指针函数将工作...?我想我得到这个窍门,但我现在还没有把我的头。

修改

我不知道是谁这个人再不过,有人发现这个线程来了。如果找到的 成员函数指针和最快的C ++委托 的让步函数指针和成员函数指针的一个非常好的介绍。

修改

得到它的工作,改变了SimpleTimer库使用这个系统代表:
HTTP://www.$c$cproject.com/KB/cpp/FastDelegate的.aspx

它集成非常漂亮,它可能是好的,有一个标准的委托系统这样的Arduino的库。

code作为测试(工作)

的typedef

 的typedef FastDelegate0<> FuncDelegate;

code机器人类:

 无效机器人::测试(){
    FuncDelegate f_delegate;
    f_delegate = MakeDelegate(这一点,和放大器;机器人::停止);    timer.setTimerDelg(1,f_delegate,1);
}无效机器人::停止(){
    Serial.println(TEST);
}

code在SimpleTimer类:

  INT SimpleTimer :: setTimerDelg(长D,FuncDelegate楼INT N){
    F();
}

Arduino的打印测试在控制台中。

下一步将它放在一个阵列,看不出有很多问题存在。谢谢大家,我简直不敢相信我在两天内学到东西。

那是什么味道?是的气味......?成功了!

对于那些有兴趣时,使用代表系统并不等于内存容量的问题:
随着FastDelegate

  AVR内存使用
----------------
设备:atmega2560计划:17178字节(6.6%满)
(+的.text +。数据.bootloader)数据:1292字节(15.8%满)
(。数据的.bss + + .noinit)
成品建设:sizedummy

无FastDelegate:

  AVR内存使用
----------------
设备:atmega2560计划:17030字节(6.5%满)
(+的.text +。数据.bootloader)数据:1292字节(15.8%满)
(。数据的.bss + + .noinit)
成品建设:sizedummy


解决方案

您可以通过做一个的仿函数对象,充当定时器code和你的code之间的代理。

 类MyHaltStruct
{
上市:
    MyHaltStruct(机器人&安培;机器人)
        :m_robot(机器人)
        {}    void运算符()()
        {robot.halt(); }私人的:
    机器人和放大器; m_robot;
}// ...timer.setTimer(时间,MyHaltStruct(*此),1);

修改

如果无法通过仿函数对象来完成,你可以全局变量和函数代替,也许在一个命名空间:

 命名空间my_robot_halter
{
    机器人*机器人= 0;    无效停止()
    {
        如果(机器人)
            机器人 - >停止();
    }
}// ...my_robot_halter ::机器人=这一点;
timer.setTimer(时间,my_robot_halter ::停止,1);

如果你有一个机器人实例,但这种方法只适用。

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.

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

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.

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.

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

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.

I tried:

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...

EDIT

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.

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.

EDIT

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.

EDIT

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

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

Code as in test (working)

typedef

typedef FastDelegate0<> FuncDelegate;

Code in robot class:

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

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

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

Code in SimpleTimer class:

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

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!

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

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

解决方案

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天全站免登陆