问题描述
我被卡住了。我试图形成一个函数,将吃无类的函数指针和来自对象的。这是我现在的代码,希望解释更多。
(应该运行在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 ++带/不带类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!