callback-回调函数

简单回调实现

示例为esp32c3使用回调函数的简单测试

点击查看代码
#include "bt.h"

void callBack()
{
  Serial.println("终于下载结束啦~");

  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  delay(5000);
  digitalWrite(12, LOW);

  Serial.println("byte");
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  BtDownlower bt(&callBack);
  bt.Download("http://xyz/xxx.mp4");
}

void loop()
{
}

bt.h文件的内容

点击查看代码
#ifndef BT_H
#define BT_H

#include "Arduino.h"

class BtDownlower
{
public:
    void Download(String url);
    void (*callBackPtr)();

    BtDownlower(void (*callBackPtr_p)())
    {
        callBackPtr = callBackPtr_p;
    }
};

void BtDownlower::Download(String url)
{

    for (int i = 0; i <= 100; i++)
    {
        delay(50);
        Serial.println("正在下载 " + url + " - " + String(i) + "%");
    }

    //下载完成,执行用户的call Back function
    callBackPtr();
}

#endif

以下为合宙esp32C3在platformIO中的ini配置

[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
board_build.flash_mode = dio


带参数回调函数

main.cpp

点击查看代码
#include "bt.h"

BtDownlower bt;

void callBack(int progress)
{
  Serial.print("正在下载 - ");
  Serial.print(progress);
  Serial.println("%");

  // 执行其他处理逻辑...
}

void setup()
{
  Serial.begin(9600);

  bt.setCallback(callBack);
  bt.Download("http://xyz/xxx.mp4");
}

void loop()
{
  // 在这里可以执行其他任务或等待回调函数的触发
  delay(1000);
  Serial.println("等待");
}

bt.h

点击查看代码
#ifndef BT_H
#define BT_H

#include "Arduino.h"

class BtDownlower
{
public:
    void Download(String url);
    void setCallback(void (*callBackPtr)(int));

private:
    void (*callBackPtr)(int);
};

void BtDownlower::Download(String url)
{
    for (int i = 0; i <= 100; i++)
    {
        delay(50);
        // 下载进度作为参数传递给回调函数
        if (callBackPtr != NULL)
        {
            callBackPtr(i);
        }
    }
}

void BtDownlower::setCallback(void (*callBackPtr)(int))
{
    this->callBackPtr = callBackPtr;
}

#endif

在这个进阶版的代码中,回调函数 callBack() 带有一个整数类型的参数 progress,该参数表示下载进度。在 Download() 函数中,每次循环迭代时,都将当前的下载进度作为参数传递给回调函数。

请注意,我对 setCallback() 函数的实现进行了修改,使用了 this->callBackPtr 来明确指向类成员变量 callBackPtr,以避免命名冲突。

支持多个回调函数

上述的代码已经支持带参数的回调函数,但每次只能设置一个回调函数。为了更灵活地处理不同的回调逻辑,我们可以支持多个回调函数。

下面是改进后的代码:
main.cpp

点击查看代码
#include "bt.h"

BtDownlower bt;

void callBack1(int progress)
{
  Serial.print("回调函数1 - 下载进度: ");
  Serial.print(progress);
  Serial.println("%");

  // 执行其他处理逻辑...
}

void callBack2(int progress)
{
  Serial.print("回调函数2 - 下载进度: ");
  Serial.print(progress);
  Serial.println("%");

  // 执行其他处理逻辑...
}

void setup()
{
  Serial.begin(9600);

  // 设置回调函数
  bt.addCallback(callBack1);
  bt.addCallback(callBack2);

  bt.Download("http://xyz/xxx.mp4");
}

void loop()
{
  // 在这里可以执行其他任务或等待回调函数的触发
  delay(1000);
  Serial.println("等待");
}

bt.h:

点击查看代码
#ifndef BT_H
#define BT_H

#include "Arduino.h"

const int MAX_CALLBACKS = 5; // 最大回调函数数量

class BtDownlower
{
public:
    void Download(String url);
    void addCallback(void (*callBackPtr)(int));

private:
    void (*callbacks[MAX_CALLBACKS])(int);
    int numCallbacks = 0;
};

void BtDownlower::Download(String url)
{
    for (int i = 0; i <= 100; i++)
    {
        delay(50);
        // 下载进度作为参数传递给所有回调函数
        for (int j = 0; j < numCallbacks; j++)
        {
            if (callbacks[j] != NULL)
            {
                callbacks[j](i);
            }
        }
    }
}

void BtDownlower::addCallback(void (*callBackPtr)(int))
{
    if (numCallbacks < MAX_CALLBACKS)
    {
        callbacks[numCallbacks++] = callBackPtr;
    }
    else
    {
        Serial.println("无法添加更多的回调函数!");
    }
}

#endif

现在,我们可以通过调用 addCallback() 方法来添加多个回调函数,每个回调函数都会接收到下载进度作为参数,并执行相应的逻辑。注意,MAX_CALLBACKS 定义了回调函数的最大数量,如果超过了该限制,将无法添加更多的回调函数。

通过支持多个回调函数,我们可以更好地扩展和定制下载过程中的不同操作和处理逻辑。

posted @ 2022-09-17 16:01  Dapenson  阅读(114)  评论(0编辑  收藏  举报