我正在尝试实现此库的NeopixelAnimator类:https://github.com/Makuna/NeoPixelBus。
我创建了一个动画类,其中包含该库的NeoPixelAnimator类的实例。要运行动画,我必须调用:.StartAnimation(uint16_t indexAnimation, uint16_t duration, UpdateCallback animUpdate)
。
我的目标是制作一排又一组的动画。第二个动画应在第一个动画完成后开始。由于该库本身不提供执行此操作的方法,因此我创建了一个代表队列的矢量,它包含要进行动画处理的动画及其颜色。
问题在于.StartAnimation()
函数需要一个UpdateCallback
参数,该参数是一个回调函数,只要调用.UpdateAnimations()
函数就被触发。
动画将由连接到Arduino Due的开关触发,该开关调用.add()
函数(示例代码中未列出)。现在,我想通过在.init()
中添加一个动画来测试它是否有效。
我的计划是创建一个指向这些回调函数的函数指针数组。问题是我无法匹配数据类型。
我们将不胜感激。此外,对于如何解决此类问题以及如何构建代码的反馈也将不胜感激。
我正在将platformIO与Arduino Due板上的Arduino库一起使用。
defines.h:
//Amount of different animations should correspond to the number of callback functions
#define NUMBER_OF_ANIMATIONS 2
//Animation ID's:
#define WIPE_ANIM 0
//Colour ID's:
#define GREEN 0
animator.h:
#include <arduino.h>
#include <NeoPixelAnimator.h>
#include <NeoPixelBrightnessBus.h>
#include <array>
#include <vector>
class Animator
{
public:
private:
//NeoPixel animation time management object
NeoPixelAnimator animations;
//Neopixel strip communication object
NeoPixelBrightnessBus<NeoGrbFeature, Neo800KbpsMethod> strip1; //NeoPixel strip 1 object
//Array of AnimUpdateCallback function pointers to the animation callback functions
AnimUpdateCallback (*_callbackPt[NUMBER_OF_ANIMATIONS])(const AnimationParam ¶m);
//Vector of arrays to store animations to be animated (animId, colorId)
std::vector<std::array<uint8_t, 2>> _animationQueue;
public:
Animator();
void init();
void run();
void add(uint8_t animId, uint8_t colorId);
private:
void updateQueue();
animator.cpp:
#include <Animator.h>
//Default constructor
Animator::Animator() : strip1(NUMBER_OF_LEDS_1, LED_PIN_1),
_callbackPt{wipeColorAnim, wipeColorAnim}
{
}
//Inititalisation function, inits strips, sets brightness for strips, sets inital color with wipeColorAnim()
void Animator::init()
{
strip1.Begin();
strip1.SetBrightness(100);
add(WIPE_ANIM, GREEN); //wipeColor strip1 with Green
}
//Add aniamtion to the queue
void Animator::add(uint8_t animId, uint8_t colorId)
{
//Create array storing the animation ID and its color
std::array<uint8_t, 2> animation{animId, colorId};
//Add the animation to the end of the queue
_animationQueue.push_back(animation);
}
//Loop this function to update animations
void Animator::run()
{
//if there is an animation running
if (animations.IsAnimating())
{
animations.UpdateAnimations(); //update running animation
strip1.Show();
}
else
{
updateQueue();
}
}
//Checks whether there is an animation in the queue if so it's started
void Animator::updateQueue()
{
//if there is an animation waiting in the queue
if (!_animationQueue.empty())
{
//Start next animation in queue on channel 0 with specified time and animUpdate callback function (channel, time, callback)
animations.StartAnimation(0, _animationQueue[0][1], _callbackPt[_animationQueue[0][0]]);
//Remove the just started animation from the queue
_animationQueue.erase(_animationQueue.begin());
}
}
main.cpp:
Animator animator;
void setup()
{
animator.init();
}
void loop()
{
//Put new animation requests in queue and update animations
animator.run();
}
platformio.ini:
[env:due]
lib_ldf_mode = chain+
platform = atmelsam
board = due
framework = arduino
monitor_speed = 115200
monitor_port = COM16
lib_deps =
NeoPixelBus
调用animations.StartAnimation(0, _animationQueue[0][1], _callbackPt[_animationQueue[0][0]]);
不会产生任何编译错误。尝试使函数指针数组中的回调函数无效化
类型“ AnimUpdateCallback (Animator::*)(const AnimationParam ¶m)
”的值不能用于初始化类型“ AnimUpdateCallback (*)(const AnimationParam ¶m)
”的实体
我的主要困惑是:
我的类中的回调函数的数据类型应为(void
或AnimUpdateCallback
)?
为什么必须在(const AnimationParam ¶m)
的末尾添加(*_callbackPt[NUMBER_OF_ANIMATIONS])
,否则我会收到一个错误,即数据类型也不匹配
答案 0 :(得分:1)
类型“
AnimUpdateCallback (Animator::*)(const AnimationParam ¶m)
”的值不能用于初始化类型“AnimUpdateCallback (*)(const AnimationParam ¶m)
”的实体
是真的。我没有看到导致此错误的代码,但是大概您正在使用Animator
的非静态成员函数来初始化数组的元素。 (是wipeColorAnim
是什么?成员函数吗?未在问题内声明。)由于非静态成员函数具有隐藏参数(this
指针),因此它们与以下对象不兼容:非成员函数。如果您的成员函数不需要this
参数,则将其声明为static
。 (如果确实需要this
,则说明您遇到了更大的设计问题。)
我的类中的回调函数的数据类型应该是(
void
或AnimUpdateCallback
)?
好吧,void
不是函数类型,所以我想这已经排除了,只剩下一个选择...(除非您是指返回类型,而不是数据类型?数据类型会是函数签名,包括返回类型和参数类型。)
为什么必须在
(const AnimationParam ¶m)
的末尾添加(*_callbackPt[NUMBER_OF_ANIMATIONS])
,否则我会收到一个错误,即数据类型也不匹配
我想一个很好的解释方式是查看声明将声明什么。
AnimUpdateCallback (*_callbackPt[NUMBER_OF_ANIMATIONS])(const AnimationParam ¶m);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- an array of pointers
最里面的部分是一个指向某物的指针数组。要查看它们指向的类型,请将最里面的部分压缩为一个星号:
AnimUpdateCallback (*)(const AnimationParam ¶m);
这是指向一个函数的指针,该函数采用单个参数(类型为const AnimationParam &
)并返回类型为AnimUpdateCallback
的值。这里的“ param
”标识符是多余的。
没有最后的部分,您只需
AnimUpdateCallback (*_callbackPt[NUMBER_OF_ANIMATIONS]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- an array of pointers
这次更容易看到指向类型:AnimUpdateCallback
。
因此,无论哪种情况,您都可以获取类型AnimUpdateCallback
的值。在前一种情况下,您将访问数组的元素,调用其指向的函数,然后查看返回的值,例如:_callbackPt[0](param)
。在后一种情况下,您只需访问数组的元素,例如:_callbackPt[0]
。正确的格式取决于您打算如何使用此数组。 (NeoPixelAnimator
的声明不是直接在问题中,因此我不知道它作为NeoPixelAnimator::StartAnimation()
的参数的期望。)