精华内容
下载资源
问答
  • 回调函数与注册函数

    千次阅读 2012-06-23 16:31:07
    在c++中,注册函数的参数是回调函数指针。 在java中,该参数是类和接口来实现的。   注册函数所在的类,是调用回调函数的决定者,决定何时何种条件下去调用回调函数。而真正实现回调函数功能的类,不会直接调用...

    在c++中,注册函数的参数是回调函数指针。

    在java中,该参数是类和接口来实现的。

     

    注册函数所在的类,是调用回调函数的决定者,决定何时何种条件下去调用回调函数。而真正实现回调函数功能的类,不会直接调用该回调函数。一般来说,会把回调函数通过注册函数,保存在注册函数所在类的成员变量中,在适当的时候,通过该成员变量去访问注册过的回调函数。

     

    在c++中,该成员变量是同种类型的函数指针。

    在java中,则是该类的对象。也可以是该类的父类或者实现的接口的对象。


    展开全文
  • 回调函数 注册

    千次阅读 2016-05-14 15:48:14
    C语言回调函数注册 续接上一节 回调函数数组简介及运行思路 回调函数注册是把一个普通函数注册为一个回调函数的过程,本例中通过分析main函数执行过程,来详细了解回到函数注册思路。 main函数执行过程: 1、...

    ##C语言回调函数–注册##
    续接上一节
    ###回调函数数组简介及运行思路###
      回调函数的注册是把一个普通函数注册为一个回调函数的过程,本例中通过分析main函数执行过程,来详细了解回调函数注册思路。
    main函数执行过程:
    1、首先按照CBDemo格式声明结构体变量demo,用于注册回调函数,再对k赋值。
     按照Data格式声明结构体变量data,用于存储回调函数要用的数据,再对i,j赋值。
    2、硬件初始化,包括LED、UART、Button。
    3、使用RegisterCallback将Test函数注册为回调函数,传入参数为:注册回调函数的结构体demo、被注册函数Test、数据参数data。
    注:RegisterCallback函数出传入三个重要参数;
      参数1:CBDemo *pDemo 是用于注册回调函数的结构体,该结构体包括CBTest类型回调函数和 void * 类型回调函数参数;
      参数2:CBTest Test为指向被注册函数的指针;
      参数3:void *p 传入回调函数被调用时使用的参数;
      在注册过程中将参数2即将被注册为回调的函数地址,赋值给参数1结构体中的–>cb元素;将参数3即回调函数被调用时使用的参数,赋值给参数1结构体中给的–>cbParam元素。

    4、串口打印data中的i,j两个数据,由于只注册未执行,因此输出结果为:10,11。
    5、通过demo.cb(demo.cbParam)调用回调函数,Test的到执行,因此输出结果为:11,12。
    6、按照上述第3条步骤,使用RegisterCallback将Test2函数注册为回调函数.
    7、串口打印demp中的k数据,由于只注册未执行,因此输出结果为:1。
    8、通过demo.cb(demo.cbParam)调用回调函数,Test2的到执行,因此输出结果为:10。
    运行结果


    一、首先使用typedef声明执行函数的指针类型,返回值类型、参数类型
    格式:typedef void(*CBTest)(void *p); 即:返回值(指针名)(参数列表)
    例:typedef void(*CBTest)(void *p);

    二、声明用于注册回调函数的结构体
    格式:同正常结构体声明方法
    例:

    typedef struct _cbDemo CBDemo;
    
    struct _cbDemo
    {
        CBTest cb; 		//指向回调函数的指针
        void * cbParam; 	//指向参数的指针
        int k;
    };
    

    三、声明用于存储函数数据成员变量的结构体
    格式:同正常结构体声明
    例:

    typedef struct _Data Data;
    struct _Data    //包含i、j两个整形成员变量
    {
        int i;
        int j;
    };
    

    四、声明要作为回调函数的两个函数:Test()和Test2()
    格式:void Test(void *p),同正常函数声明,传入参数为指针。
    例:

    void Test(void *p)
    {
        ((Data*)p)->i++;	
        ((Data*)p)->j++;
    }
    void Test2(void *p)
    {
    	((CBDemo*)p)->k = 10;
    }
    

    五、声明用于注册回调函数的函数
    格式:void RegisterCallback(CBDemo *pDemo,CBTest Test , void *p),同正常函数声明过程。参数:pDemo:用于注册回调函数的结构体;test:要注册的回调函数;p:回调函数被调用时使用的参数。
    例:

    void RegisterCallback(CBDemo *pDemo,CBTest Test , void *p)
    {
    	pDemo ->cb = Test;  //结构体的cb指向回调函数
    	pDemo ->cbParam = p; //结构体的cbParam指向参数
    }
    

    介绍部分到此为止。附main.c代码

    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nrf_gpio.h"
    #include "nrf_adc.h"
    #include "app_uart.h"
    #include "nrf_delay.h"
    #include "app_error.h"
    #include "app_timer.h"
    #include "app_button.h"
    
    #define  RX_PIN_NUMBER	11
    #define  TX_PIN_NUMBER	9
    #define  RTS_PIN_NUMBER	8
    #define  CTS_PIN_NUMBER	10
    #define UART_TX_BUF_SIZE 128 /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 128
    
    #define LED0 18
    #define LED1 19
    #define BUTTON0 16
    #define BUTTON1 17
    #define BUTTONS_NUMBER 2
    
    #define APP_TIMER_PRESCALER 0
    #define APP_TIMER_MAX_TIMERS 8
    #define APP_TIMER_OP_QUEUE_SIZE	8
    
    uint32_t err_code;
    static void lfclk_config(void);
    void uart_error_handle(app_uart_evt_t * p_event);
    void uart_init(void);
    void button_event_handler(uint8_t pin_no, uint8_t button_action);
    void app_button_user_init(void);
    
    typedef void(*CBTest)(void *p);	
    typedef struct _cbDemo CBDemo;
    struct _cbDemo
    {
    	CBTest cb;
    	void *cbParam;
    	int k;
    };
    typedef struct _Data Data;
    struct _Data
    {
    	int i;
    	int j;
    };
    void Test(void *p)
    {
    	((Data*)p)->i++;
    	((Data*)p)->j++;
    }
    void Test2(void *p)
    {
    	((CBDemo*)p)->k = 10;
    }
    void RegisterCallback(CBDemo *pDemo,CBTest Test,void *p)
    {
    	pDemo->cb = Test;
    	pDemo->cbParam = p;
    }
    
    int main()
    {
    	CBDemo demo;
    	Data data;
    	data.i = 10;
    	data.j = 11;
    	demo.k = 1;
    	nrf_gpio_cfg_output(LED0);
    	nrf_gpio_cfg_output(LED1);  
    	lfclk_config();  
    	uart_init();
    	app_button_user_init();
    	
    	RegisterCallback(&demo,Test,&data);
    	printf("%d,%d\n\r",data.i,data.j);
    	nrf_delay_ms(10);
    	demo.cb(demo.cbParam);
    	printf("%d,%d\n\r",data.i,data.j);
    	nrf_delay_ms(10);
    	RegisterCallback(&demo,Test2,&demo);
    	printf("%d\n",demo.k);
    	nrf_delay_ms(10);
    	demo.cb(demo.cbParam);
    	printf("%d\n\r",demo.k);
    	nrf_delay_ms(10);
    	while(1)
        {
        }
    }
    
    void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
        	APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
        	APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    
    void uart_init(void)
    {
        const app_uart_comm_params_t comm_params =
        {
    	    RX_PIN_NUMBER,
    	    TX_PIN_NUMBER,
    	    RTS_PIN_NUMBER,
    	    CTS_PIN_NUMBER,
    	    APP_UART_FLOW_CONTROL_DISABLED,
    	    false,
    	    UART_BAUDRATE_BAUDRATE_Baud115200
    	};
       APP_UART_FIFO_INIT(&comm_params,
       UART_RX_BUF_SIZE,
       UART_TX_BUF_SIZE,
       uart_error_handle,
       APP_IRQ_PRIORITY_LOW,
       err_code);
    
    APP_ERROR_CHECK(err_code);
    }
    void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
    	static uint8_t i = 0; 
    	printf("%d\n\r",i++);
    }
    void app_button_user_init(void)
    {
    	uint32_t timer_ticks = APP_TIMER_TICKS(100, APP_TIMER_PRESCALER);
    	APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
    	static app_button_cfg_t P_button[BUTTONS_NUMBER] =
    	{
    		{
    			BUTTON0,
    			APP_BUTTON_ACTIVE_LOW,
    			NRF_GPIO_PIN_NOPULL,
    			button_event_handler
    		},
    		{
    			BUTTON1,
    			APP_BUTTON_ACTIVE_LOW,
    			NRF_GPIO_PIN_NOPULL,
    			button_event_handler
    		}
    	};
    	err_code = app_button_init((app_button_cfg_t *)P_button,BUTTONS_NUMBER,timer_ticks);
    	err_code = app_button_enable();
    }
    static void lfclk_config(void)
    {
        NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
        NRF_CLOCK->TASKS_LFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
        {
       	 //Do nothing.
        }
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    }
    

    个人见解,仅供参考,希望能够与诸位共同讨论分析

    展开全文
  • 注册回调函数实现方法

    千次阅读 2019-04-12 12:34:07
    回调函数(callback):回调函数就是在框架设计之初留下一个还未实现的接口,供后来人去实现(不实现也没事)。也可以理解在别人的函数中“插一脚”,有一种“你的过去我来不及参与,你的未来我奉陪到底”。 看代码...

    前言

    回调函数(callback):回调函数就是在框架设计之初留下一个还未实现的接口,供后来人去实现(不实现也没事)。也可以理解在别人的函数中“插一脚”,有一种“你的过去我来不及参与,你的未来我奉陪到底”。 看代码的时候是不是总能看到api提供了一个注册函数,这个被封装,你是否好奇他是如何实现的?

    话不多说,上代码

    回调函数是由函数指针来实现的,在看这个之前先要了解函数指针哦

    int (*p[5])() = {NULL};  // 创建一个函数指针数组
    int main(int argc, char * argv[])  // 这个一般情况时官方封装成一个库函数,上电就会一直运行,类似守护进程
    {
    		register_hook_callback(test01);
    		register_hook_callback(test02);
    		 while(1)
    	    {
    	        hook();
    	        printf("=====运行========\n");
    	        Sleep(1000);
    	    }
    }
    
    int hook()  // 官方封装起来
    {
        int i = 0;
        for(i=0; i<5; i++)
        {
            if(p[i] != NULL)
            {
                p[i]();
            }
        }
    }
    
    int register_hook_callback(int (*p_callback)())  // 只是提供一个注册函数
    {
        int i = 0;
        for(i=0; i<5; i++)
        {
            if(p[i] == NULL)
            {
                p[i] = p_callback;
                break;
            }
        }
    }
    
    int test01()  // 用户自己要添加的注册函数的函数
    {
        printf("\ntest01 callback\n");
    }
    int test02()
    {
        printf("\ntest02 callback\n");
    }
    

    运行结果

    test01 callback
    
    test02 callback
    =====运行========
    
    test01 callback
    
    test02 callback
    =====运行========
    

    后言

    相信有人注意到这个回调函数怎么无法传递参数呢!!! 0.0 还没研究到呢 过几天弄好了在分享一下,需要的关注下

    展开全文
  • 回调函数

    千次阅读 2019-08-31 13:14:26
    2、注册回调函数:使用回调函数的一方。它定义一个接受函数指针的接口来接受回调函数的地址,在需要的时候调用回调函数。 3、定义回调函数的步骤: (1)确定好回调函数的形参格式。 (2)确定谁写回调函数,谁写...

    1、回调函数:是指通过函数指针调用的函数。它是定义给别人调用的函数,自己不使用。

    2、注册回调函数:使用回调函数的一方。它定义一个接受函数指针的接口来接受回调函数的地址,在需要的时候调用回调函数。

    3、定义回调函数的步骤:

    (1)确定好回调函数的形参格式。

    (2)确定谁写回调函数,谁写注册回调函数。

    (3)实现回调函数。

    (4)回调函数可用来获取状态信息(取值),也可以用来下发信息(传值)。

    4、简单的使用:

    #include <iostream>
    
    using namespace std;
    //注册回调函数(调用回调函数的函数)
    class CGisterCallBack
    {
    public:	//构造与析构
    	CGisterCallBack() {
    		m_pFunc = NULL;
    	};
    	~CGisterCallBack() {
    		if (NULL != m_pFunc)
    			m_pFunc = NULL;	//函数指针不能删除
    	}
    
    public:	//函数
    	typedef void(*pFunc)(int ID, double time);	//回调函数的格式
    	void registerFun(pFunc pF) { m_pFunc = pF; }//注册回调函数
    	void RunCallBack() { m_pFunc(1, 30.0);}		//执行别的模块注册过来的回调函数
    
    public:	//变量
    	pFunc m_pFunc;	//函数指针
    };
    
    //回调函数
    void callBack(int ID, double time)
    {
    	cout << "在" << time <<"s," << ID << "调用回调函数"  << endl;
    }
    
    //主函数
    int main()
    {
    	CGisterCallBack mCGisterCallBack;
    	mCGisterCallBack.registerFun(callBack);
    	mCGisterCallBack.RunCallBack();
    	system("pause");
    }

    输出:在30s,1调用回调函数

    展开全文
  • CallBack函数 回调函数

    千次阅读 2014-03-07 17:05:08
    如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,...
  • C++的函数代码如下,注册接口为cppfunction,回调函数为pFunc,其参数为PARA结构体。 ``` void cppfunction(void (*pFunc)(PARA*)) ``` 通过动态注册JNI的方式,cppfunction的函数签名该如何书写?直接将其参数标为...
  • 函数注册与回调【经验】

    千次阅读 2017-09-07 16:21:36
    函数注册与回调【经验】刚工作不久,就遇到了让大多数程序员新人头疼的函数注册与回调问题。因此,特意记录一遍博文。既是问题解决经验的总结,也是分享。
  • C回调函数

    千次阅读 2019-05-21 19:03:14
    回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针(地址)作为...1、首先使用回调函数,就会用到怎么注册回调函数这个问题。你需要告诉底层代码,它需要调用的函数是什么,那么就得事先定义好回调函数...
  • C#在C++编写的DLL中注册函数回调

    千次阅读 2015-08-22 13:12:39
    一个简单的Demo 描述了C#在C++中注册回调函数的过程
  • (六)注册回调函数

    2019-08-21 16:50:50
    glultReshapeFunc 注册当前窗口的形状变化回调函数 glutMouseFunc 注册当前窗口的鼠标回调函数 glutMotionFunc 设置移动回调函数 glutIdleFunc 设置全局的空闲回调函数 glutVisibilityFunc 设置当前窗口的可视回调...
  • 回调函数的好处 回调函数是一个通过函数指针调用的函数。 回调允许函数调用者在运行时调整原始函数的行为。因为可以把调用者被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制...
  • 1.回调函数基本定义- 什么是函数指针 通俗来说,函数指针是一个指向特定函数的指针。函数的类型由其参数及返回类型共同决定,函数具体名称无关。示例代码如下:int testFun1(int param1,long param2,float param3...
  • C++回调函数使用心得

    万次阅读 多人点赞 2018-11-11 15:23:52
    C++回调函数使用心得前言回调函数也是普通函数C回调函数C++回调函数使用场景描述C++回调函数定义静态成员函数访问非静态成员函数的方法回调对象更复杂的讨论 前言 关于C++回调函数的介绍网上有很多,要知道它的...
  • c++ 注册回调函数研究

    万次阅读 2016-08-19 15:18:03
    连接高层和底层就叫注册回调函数。高层程序C1调用底层程序C2,而在底层程序C2 又调用了高层程序C2的callback函数,那么这个callback函数对于高层程序C1来说就是回调函数。 在设计模式中这个方式叫回调模式。 二 ...
  • 回调函数详解

    千次阅读 2018-12-04 19:26:53
    一、什么是回调函数   回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你...
  • 函数指针与回调函数

    千次阅读 2018-03-10 19:07:46
    函数有它的地址,程序运行起来了,程序里肯定有地方要放这个函数。我们知道可以用printf %p来输出一个变量的地址,数组的地址,同样我们定义了一个函数后,用这个函数的名字做输出,就可以得到这个函数的地址。那么...
  • Z-stack中回调函数及回调机制的分析

    千次阅读 2015-05-15 17:21:47
    1、注册回调函数  ZDO_RegisterForZDOMsg( ZDAppTaskID, Device_annce ); 2、回调函数 调用, 细节:#if/**/ZG_BUILD_RTR_TYPE //131223zcl:路由节点向用户指示新节点加入  case Device_annce://问题:每次上...
  • 回调函数 结构体

    千次阅读 2016-05-07 19:08:05
    C语言回调函数–结构体 续接上一节 回调函数的一种概括 应用于异步事件的处理,首先将异步事件发生时需要执行的代码编写成一个函数,并将该函数注册成为回调函数,这样当该异步事件发生时,系统会自动调用事先注册...
  • C++调用C#注册回调函数

    千次阅读 2017-12-28 19:12:01
    本文主要讲解C#注册回调函数提供给C++调用,用于异步通知机制。这在编程过程中是经常需要用到的模式。 此过程需要创建三个工程: 1. C++动态库工程 2. C++ CLR 托管动态库工程 3. C# 测试工程 接着前文C++封装...
  • 回调函数定义

    千次阅读 2015-06-30 10:24:26
    回调函数
  • 本贴不讨论mfc是否过时...,难道窗口上控件都是共用同一个窗口回调函数的吗,但是在创建这些组件时也没有显示注册窗口过程为父窗口的回调函数啊,这些控件的回调函数在哪里,为啥没有注册窗口过程也能工作的好好的?
  • 回调函数总结

    千次阅读 2017-03-24 16:01:19
    所谓回调,就是模块A要通过模块B的某个函数b()完成一定的功能,但是函数b()自己无法实现全部功能,需要反过头来调用模块A中的某个函数a()来完成,这个a()就是回调函数 2.使用回调函数步骤 1).约定接口...
  • C#委托,事件与回调函数详解

    千次阅读 2016-06-15 16:08:24
    C#委托事件,回调函数详解
  • 1,回调函数回调函数的原理是使用函数指针实现类似“软中断”的概念。 比如在上层的两个函数A和B,把自己的函数指针传给了C,C通过调用A和B的函数指针达到“当做了什么,通知上层来调用A或者B”...
  • 之前博主给大家分享到了信号的概念和初步介绍signal函数的形式后就没有继续往下介绍了,实在是因为时间不够,那个时候博主还要上课,现在博主放假了就好好给大家分享一下如何注册信号捕捉,以及信号捕捉器的妙用。...
  • 回调函数 函数指针

    千次阅读 2013-11-02 12:08:36
    回调函数是指通过函数参数传递给其他代码的某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。 回调的用途十分广泛。例如,假设有一个函数,其功能为读取配置文件并由文件内容设置对应的...
  • C语言 — 函数注册回调

    千次阅读 2019-09-03 23:21:11
    函数注册回调函数 1、什么是函数注册和回调 ...回调函数可以把调用者被调用者分开,所以调用者不关心谁是被调用者以及被调用者如何实现。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之...
  • boost::function与回调函数

    千次阅读 2016-07-24 23:31:54
    :function与回调函数这是我在学习陈硕muduo网络库过程中记录的关于C++的知识碎片,对muduo感兴趣的同学可以加入QQ群365972535一起讨论:利用 boost::function 存储 普通函数、类成员函数、函数对象,实现函数回调的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 191,260
精华内容 76,504
关键字:

注册函数与回调函数