回调函数

C++ SDK提供回调函数接口给Android/iOS 集成 C++如何提供跨平台的回调函数接口是业务开发很常遇到的需求,但是实际上公开的资料都很杂乱,而且不一定正确,因此在此文章中,以Android Java和iOS Swift为例,系统化说明一下如何制作一个跨平台C++回调函数接口。 阅读详情

       在说回调函数之前,首先要搞清楚什么是函数指针:它就是一个函数在编译时被分配的入口地址,可以将该地址赋给一个指针,这样指针地址变量持有函数入口地址,它就指向了该函数,所以称这种指针为指向函数的指针,简称函数指针。在说明函数指针时,同时也要描述指针所指向的函数的参数类型和个数,如 :

     int (*funp)(int a , int b) ; 其中funp就是一个函数指针,它指向带有两个int 类型参数的函数。
    在C++中,单独的一个函数名(其后不跟圆括号),被自动的转化为该函数的入口地址,也就是该函数第一条指令的地址。因此,当把一个函数的地址赋给一个指针变量时,对该指针的操作就等同于调用该函数。
    说了那么多,总结一下就是:
    函数指针是一个指向函数的指针变量,它是专门来存放函数入口地址的,在程序中给它赋予哪个函数的入口地址,它就指向哪个函数,因此在一个程序中,一个函数的指针可被多次赋值,指向不同的函数。
    接下来我们来分析一下回调函数。
    下面请看一个例子:
     设一个函数process,在调用它的时候,每次实现不同的功能。输入a和b两个数,第一次调用的时找出其中的大者,第二次调用的时找出其中的小者。第三次调用求两者之和。
#include "iostream.h"
int max(int x , int y);
int min(int x , int y);
int add(int x , int y);
void process(int x , int y , int(*fun)(int , int));
//客户程序C
void main()
{
 int a,b;
 process(a,b,max);//注册回调函数
 process(a,b,min);
 process(a,b,add);
}
int max(int x , int y)
{
 return x>y?x:y;
}
int min(int x , int y)
{
 return x<y?x:y;
}
int add(int x, int y)
{
 return x + y;
}
//服务程序S
void process(int x, int y, int(* fun)(int, int))
{
 int result;
 result = (*fun)(x , y);
 return result;
}
    按照我们刚才的逻辑,其实所声明的三个功能函数:max ,min ,add 就是回调函数。
     请看:
     使用回调函数实际上就是在调用某个函数时将自己的一个函数(这个函数就是回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这是你可以利用这个机会,在回调函数中处理消息或完成一定的操作。
    也可以这样理解:
     所谓回调,就是客户程序C(main)调用服务程序S中的某个函数A(process),然后S又在某个时候反过来调用C中的某个函数B(max),对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。
     一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B叫什么,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R(process)告诉S,自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。
      下面举个通俗的例子:
      某天,我打电话向你请教问题,当然是个难题,:),你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。
 这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。       

      2. 什么情况下使用回调
      如果你是SDK的使用者,一旦别人制定了回调机制,那么你被迫得使用回调函数,因此这个问题只对SDK设计者有意义。
 从引入的目的看,回调大致分为三种:
 1) SDK有消息需要通知应用程序,比如定时器被触发;
 2) SDK的执行需要应用程序的参与,比如SDK需要你提供一种排序算法;
 3) SDK的操作比较费时,但又不能让应用程序阻塞在那里,于是采用异步方式,让调用函数及时返回,SDK另起线程在后台执行操作,待操作完成后再将结果通知应用程序。
 经上面这样一总结,你也许会恍然大悟:原来“回调机制”无处不在啊!
 是的,不光是Win32 API编程中你会用到,也不光是其它SDK编程中会用到,平时我们自己编写程序时也可能用到回调机制,这时,我们既是回调的设计者又是回调的使用者。
      3. 传统SDK回调函数设计模式
     Win32 SDK是这方面的典型例子,这类SDK的函数接口都是基于C语言的,SDK或者提供专门的注册函数,用于注册回调函数的地址,或者是在调用某个方法时才传入回调函数的地址,回调函数的原型也由于注册函数中的函数指针定义而受到约束。
 以Win32中的多媒体定时器函数为例,其原型为:
MMRESULT timeSetEvent(
  UINT uDelay,  // 定时器时间间隔,以毫秒为单位             
  UINT uResolution,          
  LPTIMECALLBACK lpTimeProc,  // 回调函数地址
  DWord dwUser,  // 用户设定的数据            

  UINT fuEvent               
);
 其中第三个参数便是用于注册回调函数的,第四个参数用于设定用户自定义数据,
        下面是回调函数的具体使用方法:
#include "stdio.h"
#include "windows.h"

#include "mmsystem.h" // 多媒体定时器需要包含此文件
#pragma comment(lib, "winmm.lib") // 多媒体定时器需要导入此库
void CALLBACK timer_proc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) // 定义回调函数
{
 printf("time out.\n");
}
int main()
{
 UINT nId = timeSetEvent( 1000, 0, timer_proc, 0, TIME_CALLBACK_FUNCTIONTIME_PERIODIC); // 注册回调函数
 getchar();
 timeKillEvent( nId );
 return 0;
}
     运行程序,我们会看到,屏幕上每隔一秒将会打印出“time out.”信息。同时我们也应该注意到,这里的timeSetEvent是异步执行的,timeSetEvent很快执行完毕,主线程继续执行,操作系统在后台负责检查timer是否超时。
 前面已经说过,本文的是站在SDK设计者的角度来看待问题,这里,我们就把前面那个通俗的例子变成程序,如下:
/// sdk.h (SDK头文件)
#ifndef __SDK_H__
#define __SDK_H__
typedef void (*HELP_CALLBACK)(const char*); // 回调函数指针
void help_me( const char* question, HELP_CALLBACK callback ); // 接口声明
#endif//__SDK_H__
/// sdk.cpp (SDK源文件,为方便,没有使用.c文件)
#include "sdk.h"
#include "stdio.h"
#include "windows.h"
HELP_CALLBACK g_callback;
void do_it() // 处理函数
{
 printf("thinking...\n");
 Sleep( 3000 );
 printf("think out.\n");
 printf("call him.\n");
 g_callback( "2." );
}
void help_me( const char* question, HELP_CALLBACK callback ) // 接口实现
{
 g_callback = callback; // 保存回调函数指针
 printf("help_me: %s\n", question);
 do_it(); // 如果采用异步方式的话,这里一般采用创建线程的方式
} 
/// app.cpp (应用程序源文件)
#include "sdk.h"
#include "stdio.h"

void got_answer( const char* msg ) // 定义回调函数
{
 printf("got_answer: %s\n", msg);
}
int main()
{
 help_me( "1+1=?", got_answer ); // 使用SDK,注册回调函数
 return 0;
}

4. C++中回调函数的设计
     C++的类中也可以使用类似上面的设计方式。如果SDK采用C语言接口,应用程序使用C++编程方式,那么类成员函数由于具有隐含的this指针而不能赋值给普通函数指针,解决方法很简单,就是为其加上static关键字
 以上面的程序为例,这里我们只看应用程序的代码:
/// app.cpp ( C++风格 )
#include "sdk.h"
#include "stdio.h"
class App
{
public:

 void ask( const char* question )
 {
  help_me( question, got_answer );
 }

 static void got_answer( const char* msg )
 {
  printf("got_answer: %s\n", msg);
 }

}; 
int main()
{
 App app;
 app.ask( "1+1=?");
 return 0;
}
    上面这种方式有个明显的缺点:由于got_answer是静态成员函数,所以它不能访问类的非静态成员变量,这可不是一件好事情。为了解决此问题,作为回调函数的设计者,你有必要为其增添一个参数,用于传递用户所需的值,如下:
/// sdk.h (SDK头文件)
#ifndef __SDK_H__
#define __SDK_H__
typedef void (*HELP_CALLBACK)(const char*, unsigned long); // 回调函数指针
void help_me( const char* question, HELP_CALLBACK callback, unsigned long user_value ); // 接口声明
#endif//__SDK_H__
/// sdk.cpp (SDK源文件,为方便,没有使用.c文件)
#include "sdk.h"
#include "stdio.h"
#include "windows.h"
HELP_CALLBACK g_callback;
unsigned long g_user_value;
void do_it()
{
 printf("thinking...\n");
 Sleep( 3000 );
 printf("think out.\n");
 printf("call him.\n");
 g_callback( "2.", g_user_value ); // 将用户设定的数据传入
}
void help_me( const char* question, HELP_CALLBACK callback, unsigned long user_value )
{
 g_callback = callback;
 g_user_value = user_value; // 保存用户设定的数据
 printf("help_me: %s\n", question);
 do_it();
}
/// app.cpp (应用程序源文件)
#include "sdk.h"
#include "stdio.h"
#include "assert.h"

class App
{
public:
 App( const char* name ) : m_name(name)
 {
 }
 void ask( const char* question )
 {
  help_me( question, got_answer, (unsigned long)this ); // 将this指针传入
 }
 static void got_answer( const char* msg, unsigned long user_value )
 {
  App* pthis = (App*)user_value; // 转换成this指针,以访问非静态数据成员
  assert( pthis );
  printf("%s got_answer: %s\n", pthis->m_name, msg);
 }
protected:
 const char* m_name;
};
int main()
{
 App app("ABC");
 app.ask( "1+1=?");
 return 0;
}
     这里的user_value被设计成unsigned long,它既可以传递整型数据,也可以传递一个地址值(因为它们在32位机器上宽度都为32),有了地址,那么像结构体变量、类对象等都可以访问了。

5. C++中回调类编程模式
     时代在不断进步,SDK不再是古老的API接口,C++面向对象编程被广泛的用到各种库中,因此回调机制也可以采用C++的一些特性来实现。
 通过前面的讲解,其实我们不难发现回调的本质便是:SDK定义出一套接口规范,应用程序按照规定实现它。这样一说是不是很简单,
想想我们C++中的继承,想想我们亲爱的抽象基类......于是,我们得到以下的代码:
/// sdk.h
#ifndef __SDK_H__
#define __SDK_H__
class Notifier // 回调类,应用程序需从此派生
{
public:
 virtual ~Notifier() { }
 virtual void got_answer(const char* answer) = 0; // 纯虚函数,用户必须实现它
};
class Sdk // Sdk提供服务的类
{
public:
 Sdk(Notifier* pnotifier); // 用户必须注册指向回调类的指针
 void help_me(const char* question);
protected:
 void do_it(); 
protected:
 Notifier* m_pnotifier; // 用于保存回调类的指针
};
#define//__SDK_H__
/// sdk.cpp
#include "sdk.h"
#include "windows.h"
#include <iostream>
using namespace std;
Sdk::Sdk(Notifier* pnotifier) : m_pnotifier(pnotifier)
{
}
void Sdk::help_me(const char* question)
{
 cout << "help_me: " << question << endl;

 do_it();
}

void Sdk::do_it()
{
 cout << "thinking..." << endl;
 Sleep( 3000 );
 cout << "think out." << endl;
 cout << "call him." << endl;
 m_pnotifier->got_answer( "2." );
}
/// app.cpp
#include "sdk.h"
class App : public Notifier // 应用程序实现一个从回调类派生的类
{
public:
 App( const char* name ) : m_sdk(this), m_name(name) // 将this指针传入
 {
 }
 void ask( const char* question )
 {
  m_sdk.help_me( question );
 }
 void got_answer( const char* answer ) // 实现纯虚接口
 {
  cout << m_name << " got_answer: " << answer << endl;
 }
protected:
 Sdk m_sdk;
 const char* m_name;
};
int main()
{
 App app("ABC");
 app.ask( "1+1=?");
 return 0;
}
        哈哈,是不是很爽?Notifier将用户必须实现的回调函数都以纯虚函数的方式定义,这样用户就不得不实现它,当然如果不是非实现不可,那么我们也可以将其定义成一般的虚函数,并像析构函数那样提供一个“空”的实现,这样用户可以在关心它时才去实现它。由于这个类的作用是实现回调,所以我们不妨称之为回调类。
 上面这种方式一简化,可以将Sdk与Notifier合并在一起。
       至此,回调函数的主要应用已经差不多写完了,关键是在程序中具体的应用,只有在具体的应用中才能真正的掌握它。

文章出处:www.diybl.com):http://www.diybl.com/course/3_program/c++/cppjs/2008920/143907_2.html

 

安卓工程接第三方SDK遇到回调函数字符串参数乱码的问题 安卓工程接第三方SDK遇到回调函数字符串参数乱码的问题在做《老王麻将》的时候,安卓工程接第三方语音SDK,出现了一个字符串乱码问题,现在总结一下。 出现的问题: 在对方发送语音的时候,SDK会通过一个接口提醒客户端有语音要去下载,这个时候客户端会传一个存语音的地址给SDK然后开始下载。下载成功之后呢,SDK会回调一个函数,把一些语音文件的具体信息还有之前客户端传入的地址一起回调回来。但是,收到的回调 阅读详情

相关推荐

【一】PCIe基础知识

Linux PCIe基础知识

他山之石 可以攻玉 4万+

回调心的

<br />最近,忙着搞个回调函数,但是我连回调函数是什么都不知道,好在经过一番修炼,略知一二,分享如下:<br /> <br />     在说回调函数之前,首先要搞清楚什么是函数指针:它就是一个函数在编译时被分配的入口地址,可以将该地址赋给一个指针,这样指针地址变量持有函数入口地址,它就指向了该函数,所以称这种指针为指向函数的指针,简称函数指针。 在说明函数指针时,同时也要描述指针所指向的函数的参数类型和个数, 如 <br />     int (*funp)(int a , int b) ; 其中fu

xuanxiaoala的专栏 348

从AMBA到USB:手把手教你评估和选择Synopsys DesignWare里的免费商用IP

本文详细介绍了如何评估和选择Synopsys DesignWare中的免费商用IP,从AMBA到USB等关键模块。通过技术参数核对、验证环境评估和集成注意事项,帮助工程师高效利用这些经过硅验证的商业级IP,提升SoC设计效率。文章还探讨了免费IP与付费IP的边界策略,避免常见陷阱。

weixin_42683394的博客 297

函数指针和回调函数对函数取地址和直接使用函数名的差距

函数的二进制代码存放在内存四区中的代码区,函数的地址是它在内存中的起始地址。如果把函数的地址作为参数传递给函数,就可以在函数中灵活的调用其它函数。函数指针和回调函数对函数取地址和直接使用函数名的差距

weixin_73303171的博客 255

【仿真】Carla Python API实战:从零搭建自动驾驶测试环境

本文详细介绍了如何使用Carla Python API从零搭建自动驾驶测试环境。通过Carla仿真平台,开发者可以构建高度逼真的城市环境和车辆物理模型,利用Python API实现传感器配置、数据采集、场景构建及自动驾驶算法集成。文章还分享了实际项目中的调试技巧和性能优化经验,帮助读者快速掌握自动驾驶仿真测试的核心技术。

weixin_29050513的博客 213

OLED的字模提取(保姆级)---基于PCtoLCD2013

做为一个刚刚开始接触编程不久的白菜,这个OLED想做一个信息显示,可是商家给我的例程里就是88,816两种字体的格式,我的屏幕是0.91寸的8*16的字体显示上感觉特别丢丢儿小,我就想整个大的,哎,只怪直接学习习惯不好,总是学一半,绕了好大一圈,才搞好,想写一篇博客,时刻提醒踏实学习,第一次写博客,小白一枚,勿喷。。 OLED屏幕驱动程序功能 我们对Markdown编辑器进行了一些功能拓展与语法支...

qq_44886611的博客 7781

【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的博客 8591

倍加福(P+F)R2000修改雷达IP

在调试车子的时候,用到了倍加福R2000的一款雷达,设备启动建图时发现建不了图,于是查看/scan发现话题无数据,尝试ping雷达接口发现ping不通,应该是IP地址与上位机端口的IP地址不对。首先查看雷达的IP地址,这个在雷达上有两个按键,按下后可以显示IP: 按两下右边的键再按一下左边的键雷达上会显示出IP号,这里拍的不是很清楚。查看到开始时雷达IP地址为192.168.111.10,而上位机ping的IP地址为192.168.188.50.与实际不同,所以需要对雷达进行配置。一台windows笔记本

YiYeZhiNian的博客 5890

C++回调函数

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

lovely_yoshino的博客 6992

【2024遥感应用组一等奖】基于时空融合和水量平衡法的若尔盖高原水源涵养功能评价

考虑到水源涵养的概念和尺度特征、数据的可获得性、模型的模拟精度等,构建了一种基于遥感、气象和水量平衡原理的草原湿地水源涵养评价方法,估算若尔盖湿地近23年(2000-2022)来的水源涵养量。若尔盖湿地是我国黄河源区的重要水源地,所以本研究以若尔盖湿地的水源涵养功能评估为科学问题,基于遥感数据、GIS数据等,利用水量平衡原理,发展计算简单、便捷、数据易获取的“水源涵养估算方法”,科学估算若尔盖湿地水源涵养服务量,探究其时空动态变化趋势及其影响因素;公式中,Z1和Z2为两个不同高度面的高度,u为摩擦速率;

JData_Engineer的博客 239

微信小程序 - 实现客户支付订单连接小票打印机自动打印订单小票功能,微信小程序如何对接小票打印机自动打印小票,小程序收到新订单的时候可以联动商家打印出小票/单据/标签/发货单/电子面单等(详细教程)

微信小程序调用小票打印机,小程序接单后小票机自动打印订单,微信小程序云开发订单微信支付与小票和标签打印的完整高效流程,如何实现微信订单连接小票打印机并自动接单打印,微信小程序连接打印机打印单据小票打印,微信小程序云开发调用小票打印机实现方案,微信小程序怎么配置小票打印机,微信支付电子小票,外卖小程序实战-接单后小票机自动打印订单,微信小程序连接蓝牙打印小票,打印购物小票,调用小票打印机打印小票,微信订单如何连接小票打印机并实现自动接单打印,实现微信订单连接小票打印机并自动接单打印,微信小程序小票打印机打印教

🏆 前端领域优质创作者 1万+

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

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

操练起来。。。 3万+

hive get_json_object解析json结果为null咋办?

最近一位开发的同学在使用get_json_object函数对json数据解析的时候,出现了结果为null的问题,问题原因是sql语法导致的,那么今天就来详细介绍一下解析json函数的用法!最后还是提醒小伙伴们,在开发过程中,一定要注意sql语法格式的书写,避免一些意想不到的结果!

笑看风云路的博客 2308

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

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

ZZU_LGY 6074

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Qt中回调函数的实现

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

sqlxby的博客 8295

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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

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

weixin_51205269的博客 1088

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

delphi 回调函数

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

╰☆斌☆╮涂鸦 7620

回调函数详解

回调函数

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 () {

一起来看烟花吧的博客 1008

回调函数 注册

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

逆光倾城的博客 4689
上一篇: 基于VS2008使用def文件创建DLL
下一篇: 正向功和反向功
sdudubing
博客等级 码龄16年 117粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值