回调函数指针C ++有/无类 [英] Callback function pointers C++ with/without classes
问题描述
我被困。我试图形成一个功能,将吃从对象无类函数指针及的。这是我目前的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屋!