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

问题描述

我被卡住了。我试图形成一个函数,将吃无类的函数指针和来自对象的。这是我现在的代码,希望解释更多。



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



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

  / * SimpleTimer  - Arduino。 
*作者:[email protected]
*版权所有(c)2010 OTTOTECNICA意大利
* /

它在这种类型的设置计时器间隔上调用它的函数:

  typedef void (* timer_callback)(void); 

据我所知,这是一个classles函数,网页 让我真的很远,但不够远。可能是我身边的术语缺陷。



现在,我已经做了我自己的类,我想依次使用这个SimpleTimer库。但如果我喂的SimpleTimer我的类函数,它不喜欢他们(我明白)。



所以有类Robot,它有 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);
}

此时c_func变量是一个无类函数,使用 Robot :: halt 函数。我看过,读,学,但还没有成功。



我试过:

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

但这一切都是相同的问题/我只是在黑暗中刺穿...



EDIT



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



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



要继续,改变SimpleTimer代码。这个类需要一个对我的停止功能的对象的引用,对吧?所以,重载的settimer函数的东西,我的对象和我的函数作为两个单独的指针将工作...?



EDIT



我不知道谁是这个人再来的,但任何人找到这个线程。如果找到了



有了它,你可以在函数指针和成员函数指针中使用。工作,将SimpleTimer库更改为使用此代理系统:



它集成非常好,在Arduino库中有一个像这样的标准委托系统可能很好。 / p>

代码如test(工作)



typedef

  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类中的代码:


$ b b

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

Arduino在控制台中打印TEST。



下一步将它放入一个数组,没有看到很多问题。感谢大家,我不敢相信我在两天内学到的东西。



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



对于感兴趣的用户,使用的Delegate系统不会占用内存容量问题:
With FastDelegate

  AVR内存使用
----------------
设备:atmega2560

程序:17178字节(6.6%满)
(.text + .data + .bootloader)

数据:1292字节(15.8%满)
.bss + .noinit)


已完成的建筑物:sizeummy

没有FastDelegate:

  AVR内存使用
--------------- -
设备:atmega2560

程序:17030字节(6.5%满)
(.text + .data + .bootloader)

数据:1292字节(15.8%满)
(.data + .bss + .noinit)


已完成的建筑物:sizedummy


解决方案

您可以通过对象,用作代码和代码之间的代理。

  class MyHaltStruct 
{
public:
MyHaltStruct(Robot& robot)
:m_robot(robot)
{}
$ b b void operator()()
{robot.halt(); }

private:
Robot& m_robot;
}

// ...

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



编辑



可以在命名空间中使用全局变量和函数:

 命名空间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);

这只适用于你有一个机器人实例。


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: [email protected]
 * 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 ++带/不带类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 08:36