什么叫回调函数

C语言:回调函数 延迟执行:回调函数在特定条件触发后才被执行,而非立即执行,这对于异步编程尤为重要,如网络请求、定时任务等。松耦合:通过回调函数,调用方和被调用方之间解耦,调用方无需了解被调用方的具体实现,只需要提供符合约定的回调函数接口即可。事件驱动:回调函数广泛应用于事件驱动编程中,例如窗口系统、GUI编程、Web前端JavaScript中的事件监听等,当事件触发时,预先定义好的回调函数会被调用。多态性和扩展性:回调函数允许用户自定义行为,增强了程序的多态性和扩展性。例如,在C语言中,通过函数指针传递回调函数; 阅读详情
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。

1 什么是回调

软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。



对于不同类型的语言(如结构化语言和对象语言)、平台(Win32、JDK)或构架(CORBA、DCOM、WebService),客户和服务的交互除了同步方式以外,都需要具备一定的异步通知机制,让服务方(或接口提供方)在某些情况下能够主动通知客户,而回调是实现异步的一个最简捷的途径。

对于一般的结构化语言,可以通过回调函数来实现回调。回调函数也是一个函数或过程,不过它是一个由调用方自己实现,供被调用方使用的特殊函数。

在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类成为回调类,回调类的对象成为回调对象。对于象C++或Object Pascal这些兼容了过程特性的对象语言,不仅提供了回调对象、回调方法等特性,也能兼容过程语言的回调函数机制。

Windows平台的消息机制也可以看作是回调的一种应用,我们通过系统提供的接口注册消息处理函数(即回调函数),从而实现接收、处理消息的目的。由于Windows平台的API是用C语言来构建的,我们可以认为它也是回调函数的一个特例。

对于分布式组件代理体系CORBA,异步处理有多种方式,如回调、事件服务、通知服务等。事件服务和通知服务是CORBA用来处理异步消息的标准服务,他们主要负责消息的处理、派发、维护等工作。对一些简单的异步处理过程,我们可以通过回调机制来实现。

下面我们集中比较具有代表性的语言(C、Object Pascal)和架构(CORBA)来分析回调的实现方式、具体作用等。




回页首


2 过程语言中的回调(C)

2.1 函数指针

回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子:

void Func(char *s);// 函数原型
void (*pFunc) (char *);//函数指针

可以看出,函数的定义和函数指针的定义非常类似。

一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。

typedef void(*pcb)(char *);

回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。

被调函数的例子:

void GetCallBack(pcb callback)
{
/*do something*/
}
用户在调用上面的函数时,需要自己实现一个pcb类型的回调函数:
void fCallback(char *s) 
{
/* do something */
} 
然后,就可以直接把fCallback当作一个变量传递给GetCallBack,
GetCallBack(fCallback);

如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。




回页首


2.2 参数传递规则

到目前为止,我们只讨论了函数指针及回调而没有去注意ANSI C/C++的编译器规范。许多编译器有几种调用规范。如在Visual C++中,可以在函数类型前加_cdecl,_stdcall或者_pascal来表示其调用规范(默认为_cdecl)。C++ Builder也支持_fastcall调用规范。调用规范影响编译器产生的给定函数名,参数传递的顺序(从右到左或从左到右),堆栈清理责任(调用者或者被调用者)以及参数传递机制(堆栈,CPU寄存器等)。

将调用规范看成是函数类型的一部分是很重要的;不能用不兼容的调用规范将地址赋值给函数指针。例如:

// 被调用函数是以int为参数,以int为返回值
__stdcall int callee(int); 
// 调用函数以函数指针为参数
void caller( __cdecl int(*ptr)(int)); 
// 在p中企图存储被调用函数地址的非法操作
__cdecl int(*p)(int) = callee; // 出错

指针p和callee()的类型不兼容,因为它们有不同的调用规范。因此不能将被调用者的地址赋值给指针p,尽管两者有相同的返回值和参数列

2.3 应用举例

C语言的标准库函数中很多地方就采用了回调函数来让用户定制处理过程。如常用的快速排序函数、二分搜索函数等。

快速排序函数原型:

void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
二分搜索函数原型:
void *bsearch(const void *key, const void *base, size_t nelem,
     size_t width, int (_USERENTRY *fcmp)(const void *, const void *));

其中fcmp就是一个回调函数的变量。

下面给出一个具体的例子:

#include <stdio.h>
#include <stdlib.h>
int sort_function( const void *a, const void *b);
int list[5] = { 54, 21, 11, 67, 22 };
int main(void)
{
   int  x;
   qsort((void *)list, 5, sizeof(list[0]), sort_function);
   for (x = 0; x < 5; x++)
      printf("%i\n", list[x]);
   return 0;
}
int sort_function( const void *a, const void *b)
{
   return *(int*)a-*(int*)b;
}

2.4 面向对象语言中的回调(Delphi)

Dephi与C++一样,为了保持与过程语言Pascal的兼容性,它在引入面向对象机制的同时,保留了以前的结构化特性。因此,对回调的实现,也有两种截然不同的模式,一种是结构化的函数回调模式,一种是面向对象的接口模式。

2.4.1 回调函数

回调函数类型定义:

type
   TCalcFunc=function (a:integer;b:integer):integer;

按照回调函数的格式自定义函数的实现,如

function Add(a:integer;b:integer):integer
begin
  result:=a+b;
end;
function Sub(a:integer;b:integer):integer
begin
  result:=a-b;
end;

回调的使用

function Calc(calc:TcalcFunc;a:integer;b:integer):integer

下面,我们就可以在我们的程序里按照需要调用这两个函数了

c:=calc(add,a,b);//c=a+b
c:=calc(sub,a,b);//c=a-b

2.4.2 回调对象

什么叫回调对象呢,它具体用在哪些场合?首先,让我们把它与回调函数对比一下,回调函数是一个定义了函数的原型,函数体则交由第三方来实现的一种动态应用模式。要实现一个回调函数,我们必须明确知道几点:该函数需要那些参数,返回什么类型的值。同样,一个回调对象也是一个定义了对象接口,但是没有具体实现的抽象类(即接口)。要实现一个回调对象,我们必须知道:它需要实现哪些方法,每个方法中有哪些参数,该方法需要放回什么值。

因此,在回调对象这种应用模式中,我们会用到接口。接口可以理解成一个定义好了但是没有实现的类,它只能通过继承的方式被别的类实现。Delphi中的接口和COM接口类似,所有的接口都继承与IInterface(等同于IUnknow),并且要实现三个基本的方法QueryInterface, _AddRef, 和_Release。

  • 定义一个接口
    type IShape=interface(IInterface)
     procedure Draw;
    end
  • 实现回调类
    type TRect=class(TObject,IShape)
     protected
          function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
          function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
        public
       procedure Draw;
    end;
    type TRound=class(TObject,IShape)
     protected
          function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
          function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
        public
       procedure Draw;
    end;
  • 使用回调对象
    procedure MyDraw(shape:IShape);
    var 
    shape:IShape;
    begin
    shape.Draw; 
    end;

如果传入的对象为TRect,那么画矩形;如果为TRound,那么就为圆形。用户也可以按照自己的意图来实现IShape接口,画出自己的图形:

MyDraw(Trect.Create);
MyDraw(Tround.Create);

2.4.3 回调方法

回调方法(Callback Method)可以看作是回调对象的一部分,Delphi对windows消息的封装就采用了回调方法这个概念。在有些场合,我们不需要按照给定的要求实现整个对象,而只要实现其中的一个方法就可以了,这是我们就会用到回调方法。

回调方法的定义如下:

TNotifyEvent = procedure(Sender: TObject) of object; 
TMyEvent=procedure(Sender:Tobject;EventId:Integer) of object;

TNotifyEvent 是Delphi中最常用的回调方法,窗体、控件的很多事件,如单击事件、关闭事件等都是采用了TnotifyEvent。回调方法的变量一般通过事件属性的方式来定义,如TCustomForm的创建事件的定义:

property OnCreate: TNotifyEvent read FOnCreate write FOnCreate stored IsForm;

我们通过给事件属性变量赋值就可以定制事件处理器。

用户定义对象(包含回调方法的对象):

type TCallback=Class
    procedure ClickFunc(sender:TObject);
end;
procedure Tcallback.ClickFunc(sender:TObject);
begin
  showmessage('the caller is clicked!');
end;

窗体对象:

type TCustomFrm=class(TForm)
  public
 procedure RegisterClickFunc(cb:procedure(sender:Tobject) of object);
end;
procedure TcustomFrm..RegisterClickFunc(cb:TNotifyEvent);
begin
  self.OnClick=cb;
end;

使用方法:

var
  frm:TcustomFrm;
begin
  frm:=TcustomFrm.Create(Application);
  frm.RegisterClickFunc(Tcallback.Create().ClickFunc);
end;




回页首


3 回调在分布式计算中的应用(CORBA)

3.1 回调接口模型

CORBA的消息传递机制有很多种,比如回调接口、事件服务和通知服务等。回调接口的原理很简单,CORBA客户和服务器都具有双重角色,即充当服务器也是客户客户。

回调接口的反向调用与正向调用往往是同时进行的,如果服务端多次调用该回调接口,那么这个回调接口就变成异步接口了。因此,回调接口在CORBA中常常充当事件注册的用途,客户端调用该注册函数时,客户函数就是回调函数,在此后的调用中,由于不需要客户端的主动参与,该函数就是实现了一种异步机制。

从CORBA规范我们知道,一个CORBA接口在服务端和客户端有不同的表现形式,在客户端一般使用桩(Stub)文件,服务端则用到框架(Skeleton)文件,接口的规格采用IDL来定义。而回调函数的引入,使得服务端和客户端都需要实现一定的桩和框架。下面是回调接口的实现模型:



3.1.1 范例

下面给出了一个使用回调的接口文件,服务端需要实现Server接口的框架,客户端需要实现CallBack的框架:

module cb
{
 interface CallBack;
 interface Server;
interface CallBack 
{
     void OnEvent(in long Source,in long msg);
};
   interface Server 
{
     long RegisterCB(in CallBack cb);
  void UnRegisterCB(in long hCb);
};
};

客户端首先通过同步方式调用服务端的接口RegistCB,用来注册回调接口CallBack。服务端收到该请求以后,就会保留该接口引用,如果发生某种事件需要向客户端通知的时候就通过该引用调用客户方的OnEvent函数,以便对方及时处理。

C++ 跨线程处理同步/异步消息 为了不阻塞主线程,将主线程发过来的命令处理为不同的事件,放到另一个线程去执行,包括同步和异步处理。 注:同一个进程,多线程。 为了保证线程间的共享资源保护以及线程间的消息机制,用到了下面几个系统库资源: std::mutex std::unique_lock std::conditional_variable 1、消息 结构体 和 事... 阅读详情

相关推荐

Android系统获取event事件回调等几种实现和原理分析

本文从源码的角度,分析了Android系统获取event事件回调的实现和原理。了解了输入事件的定义和分类,以及输入事件的获取和分发的过程和组件。我还介绍了三种实现输入事件回调的方式,即注册监听器和事件监听广播 , 重写方法,并掌握了它们的原理和优缺点。

我其实什么都不会 1975

异步消息的传递-回调机制

陈家朋 (japen@vip.sina.com)2004 年 2 月1 什么是回调软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务

smilingleo的专栏 3692

手把手教你用FreeModbus RTU协议栈实现STM32与PLC通信(附Keil工程)

本文详细介绍了如何使用FreeModbus RTU协议栈在STM32上实现与PLC的工业通信。从环境搭建、工程配置到关键移植接口实现,提供了Keil工程模板和调试技巧,帮助开发者快速掌握Modbus RTU通信技术,适用于工业自动化领域的设备间通信需求。

weixin_42549037的博客 418

不容错过!!C语言-回调函数详解

超详细回调函数

weixin_44127729的博客 6003

西门子交换机环网冗余设置(实战篇2.2)

MRP的重组时间为 200ms 因此 PROFINET 通信必须选择大于 200ms 的看门狗时间,看门狗。ET200SP默认为 2ms*3=6ms) MRP 的重组时间为 200ms 故系统会报出看门狗超时。更新,默认是 3 个周期,超出设置的周期数就会报 IO 设备故障。时间不是直接配置的,而是作为没有 IO 数据可接受的更新周期,也就是允许几个周期没有数据。来达到大于 200ms 的看门狗时间的要求(看门狗时间 可接受更新周期数 更新时间)。是IO 控制器和 IO 设备)

weixin_42580591的博客 364

IMU预积分--详细推导过程

IMU预积分推导

weixin_51547017的博客 2万+

C++回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。 回调函数机制: 1、定义一个函数(普通函数即可); 2、将此函数的地址注册给调用者; 3、特定的事件或条件发生时,调用者使用函数指针调用回调函数。 C回调函数 C++回调函数扩展自C回调函数,要想理解C++回调函数,先要理解C回调函数。我们通过

lovely_yoshino的博客 6992

【STM32Cube HAL】输入捕获(六)——PWM测量

实验内容:使用通用定时器输入捕获测量信号的脉宽(检测按键按下的时间)。 一、原理图 二、 CubeMX配置 Step1.打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F103VETx。 Step2.选择时钟源,并配置时钟树。选择Crystal/Ceramic Resonator,并配置系统时钟为72M。 Step3.配置SYS,我们这里选择的是Serial Wire。(正常情况配置不配置不影响,debug可以使用。但是你不可以把这...

HAHAHA 1万+

【c++】16.回调函数、注册回调函数

回调函数机制 使用了 函数指针。 1.定义一个函数指针,如typedef void (*func_ptr)(std::string str); 2.定义一个 回调函数 void func(std::string str),需要注意的是,回调函数必须和前面定义的函数指针参数类型和参数个数一致 3.定义一个注册回调函数 void SetCallback(func_ptr ptr);, 其中 func_ptr 是一个函数指针类型,之后会把一个回调函数地址(函数名func)赋值给 ptr; func_ptr m_p

u011754972的博客 8590

YOLOv13+SAHI实战:5步搞定无人机航拍小目标检测(附VisDrone数据集调参技巧)

本文详细介绍了如何结合YOLOv13与SAHI(切片辅助超推理)技术,在VisDrone2019数据集上实现高效的无人机航拍小目标检测。通过5个实战步骤,包括环境配置、SAHI参数解析、数据集调优、完整训练推理流程和性能优化技巧,帮助开发者显著提升小目标检测的准确率和效率。

egg99的博客 429

[网络安全自学篇] 六.OllyDbg动态分析工具基础用法及Crakeme逆向破解

这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步。上一篇文章分享了IDA Pro反汇编工具的基础用法,并简单讲解一个EXE逆向工程解密实战方法;本篇文章将讲解动态分析OllyDbg工具的基础用法,主要是结合两个Crakeme案例逆向破解。希望对初学者有帮助,大神请飘过,谢谢各位看官!

杨秀璋的专栏 1万+

回调函数的实质——什么是回调函数,为什么要使用回调函数

在C/C++里面,函数的概念很好理解,就是把某个任务独立出来,封装在一起,然后给它取个名字,它可以有参数和返回值。基本上跟数学里的函数概念一致。那么,回调函数是个什么鬼呢?它和函数到底有何异同?既然已经有了函数,为啥还非要生出个回调函数来?想必,小伙伴们在刚碰到这个概念的时候,都会被这些问题困扰。网上搜一搜,有很多相关的材料,但是未必透彻。我觉得要真正理解一个概念,必须要先理解它存在的意义,也就是

操练起来。。。 3万+

Yolov8-pose关键点检测:训练准备篇 | 自己数据集从labelme标注到生成yolo格式的关键点数据

yolov8-pose关键点检测系列:从数据集标记到生成适合yolo的关键点格式

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 5875

回调函数

1、回调函数:是指通过函数指针调用的函数。它是定义给别人调用的函数,自己不使用。 2、注册回调函数:使用回调函数的一方。它定义一个接受函数指针的接口来接受回调函数的地址,在需要的时候调用回调函数。 3、定义回调函数的步骤: (1)确定好回调函数的形参格式。 (2)确定谁写回调函数,谁写注册回调函数。 (3)实现回调函数。 (4)回调函数可用来获取状态信息(取值),也可以用来下发信息(传...

Liu_Xiao_Ming的博客 2175

Power EM与Signal EM解决办法与原理分析

1.面对power EM,首先检查missing via,补全via,还可以加宽,加密局部power mesh,一些power IO出pin有power EM问题,可以叠加多层线和垂直方向补power形成网络降低并联电阻和提供更多电流通路解决,这种方法还可以降低ir drop。3.先进工艺有一个via ladder的方法可以解决power/signal em问题,clock cell出pin绕线或者power rail连接power stripe通过搭梯子的方式连接,原理还是分流。

m0_61544122的博客 4744

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C++回调函数以及epoll中回调函数的使用

回调函数是一种常用的编程技术,它允许程序在运行时将一个函数作为参数传递给另一个函数,以实现更加灵活和可扩展的功能。在C++中,回调函数通常被实现为函数指针或者函数对象。函数指针是指向函数的指针变量,可以通过它来调用函数。函数对象是一种可调用对象,它是一个类的对象,其中定义了一个operator()函数,可以像普通函数一样进行调用。在上面的示例中,我们定义了一个回调函数类型Callback,该类型是一个函数指针,接受一个int类型的参数并返回void。

ZZU_LGY 6071

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Qt中回调函数的实现

Qt中回调函数的实现 文章目录Qt中回调函数的实现一、关于回调函数的介绍二、回调函数使用的实列1.调用回调函数的类2.回调函数实现总结 一、关于回调函数的介绍 这个关于回调函数的介绍可以查看知乎上关于回调函数的介绍通俗易懂 回调函数(callback)是什么. 上面的回答让我理解回调函数的还是[A 让 B 排序,B 会做排序,但排序需要知道哪个比哪个大,这点 B 自己不知道,就需要 A 告诉它。而判断大小本身是某种行为,既然 C 语言中不可以传进第一值的函数,就设计成传递第二值的函数指针,这个函数指针是

sqlxby的博客 8295

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

回调函数,回调函数,回调函数,什么是回调函数

这是一个关于回调函数的全面讲解

weixin_51205269的博客 1077

delphi 回调函数

       今天在DELPHI上随便编写了个回调函数的例子,怕以后忘了,赶紧给它给记下来,呵呵。觉的好简单,什么都没有,只是在同一个单元内,利用了DELPHI的多线程调用回调函数,高手别见笑哈!下次肯定要多加点东西完善滴,这次只是熟悉一下实现回调的整个过程。interfaceuses  Windows, Messages, SysUtils, Variants, Classes,

╰☆斌☆╮涂鸦 7615

回调函数详解

回调函数

m0_60237095的博客 2653

什么是回调函数

1 定义和使用场合 回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。简单来说,就是由别人的函数运行期间来回调你实现的函数。 这一设计允许了底层代码调用在高层定义的子程序(如图1-1所...

往事撩人醉的博客 6万+

回调函数究竟是什么?

深入研究到底什么是回调函数!

ricardoccc的博客 2284

回调函数 异步回调函数 同步回调函数

什么是回调函数 function test (x, y, cb) { console.log(x+y); cb(); } test(1,2, function () {alert(1)}); // 我们在调用test函数的时候传递了一个匿名函数作为实参 /***********也可以这样写***************/ function test (x, y, cb) { console.log(x+y); cb(); } function test2 () {

一起来看烟花吧的博客 1005

回调函数 注册

C语言回调函数–注册 续接上一节 回调函数数组简介及运行思路  回调函数的注册是把一个普通函数注册为一个回调函数的过程,本例中通过分析main函数执行过程,来详细了解回到函数注册思路。 main函数执行过程: 1、首先按照CBDemo格式声明结构体变量demo,用于注册回调函数,再对k赋值。  按照Data格式声明结构体变量data,用于存储回调函数要用的数据,再对i,j赋值。 2、硬件

逆光倾城的博客 4689
上一篇: c语言位操作
下一篇: fedora-16 Linux 和 win7 双系统,出现grub rescue的处理
LinuxJoey
博客等级 码龄15年 117粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值