c++ - 如何制作类型定义函数的函数指针数组
问题描述
我正在尝试实现这个库的 NeopixelAnimator 类:https ://github.com/Makuna/NeoPixelBus 。
我创建了一个动画器类,其中包含库的 NeoPixelAnimator 类的一个实例。要运行动画,我必须调用:.StartAnimation(uint16_t indexAnimation, uint16_t duration, UpdateCallback animUpdate)
.
我的目标是制作一系列动画,这些动画一个接一个。第二个动画应该在第一个动画完成后开始。由于库本身不提供执行此操作的方法,因此我创建了一个表示队列的向量,它包含要设置动画的动画及其颜色。
问题是该.StartAnimation()
函数需要一个UpdateCallback
参数,该参数是一个回调函数,每当调用该函数时就会触发该.UpdateAnimations()
函数。
动画将由连接到调用.add()
函数的 Arduino Due 的开关触发(不在示例代码中)。现在,我想通过在.init()
.
我的计划是创建一个指向这些回调函数的函数指针数组。问题是我无法让数据类型匹配。
帮助将不胜感激。此外,我们将不胜感激有关如何处理此类问题和构建代码的反馈。
我在 Arduino Due 板上使用 platformIO 和 Arduino 库。
定义.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
动画师.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();
动画师.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());
}
}
主.cpp:
Animator animator;
void setup()
{
animator.init();
}
void loop()
{
//Put new animation requests in queue and update animations
animator.run();
}
平台io.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])
,否则我会收到数据类型也不匹配的错误
解决方案
“”类型的值
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
.
因此,无论哪种情况,您都有办法获取 type 的值AnimUpdateCallback
。在前一种情况下,您将访问数组的元素,调用它指向的函数,然后查看返回值,例如:_callbackPt[0](param)
. 在后一种情况下,您只需访问数组的一个元素,例如:_callbackPt[0]
. 正确的形式取决于您打算如何使用此数组。(的声明NeoPixelAnimator
不是直接在问题中,所以我不知道它作为参数的期望是什么NeoPixelAnimator::StartAnimation()
。)
推荐阅读
- firebase - @firebase/app-types@0.x 有什么作用,我应该什么时候使用它?
- java - 我正在尝试在带有 like 子句的选择查询中使用变量,但出现错误,例如无效标识符
- javascript - 使用 D3.JS 将 CSV 转换为 JSON
- php - 如何覆盖 WordPress 插件用来链接其样式表的 URL?
- python - 如何在 Python 中获取所有内置函数的列表
- asp.net - 如何从 Sharepoint 中提取信息并显示在使用 ASP.net 和 HTML 构建的单独网站上
- git - 如何修复“您的分支比 'origin/master' 领先 1 次提交。”?
- r - 使用 R 中的网状包访问 python 库和函数
- java - Glassfish 3 将所有 http 请求重定向到 https
- mysql - MySQL JSON“不在”不起作用