赞
踩
参考:https://blog.csdn.net/qawsedrf123lala/article/details/119176116 代码修改为windows下可运行
回调函数就是通过函数指针调用函数。如果把函数的指针或者地址作为参数传递给另一个参数,当这个指针被用来调用其所指向的函数时,那么这就是一个回调的过程,这个被回调的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或者条件发生时由另外的一方调用的,用于对该事件或者条件进行响应。回调函数就是在两个独立函数或者独立类通信的通道。
回调函数是利用函数指针来实现的一种调用机制,学过GUI程序设计技术的同学肯定知道,回调函数还是GUI程序设计的底层技术。
回调机制原理:
1.调用者不知道具体事件发生时需要调用的具体函数
2.被调函数不知道何时被调用,只知道需要完成的任务
3.当具体事件发生时,调用者通过函数指针来调用具体函数
回调机制中的调用者和被调函数互不依赖。
例子:我们经常在电视剧或者电影中看到如下情节,一位主人公为了完成某个非常难的任务,这个时候一个绝世高人给了他一个锦囊,对他说你在遇到困难的时候打开这个锦囊,这个锦囊里面写的东西会告诉你怎么做。其实这里面就蕴含了回调的机制在里面。为什么呢?就比如我们把主人公去某个地方完成任务比作一个函数(调用者),然后锦囊里面的内容为一个函数(被调用者)。看看满不满足上述的3个条件。1.主人公不知道锦囊里面的内容,2.锦囊不知道什么时候会被主人公拆开,锦囊里面只写着怎么帮助主人公解决困难。3.当主人公遇到困难的时候,主人公通过打开锦囊来解决困难。
来看一个C语言程序加深大家对回调函数的理解。
#include <stdio.h>
typedef int(*Weapon)(int);
void fight(Weapon wp,int arg)
{
printf("Fight Boss!\n");
int result=0;
result=wp(arg);
printf("Boss Loss=%d\n",result);
}
int knife(int n)
{
int ret=0;
int i=0;
for(i=0;i<n;i++)
{
printf("knife attack:%d\n",1);
ret+=1;
}
return ret;
}
int sword(int n)
{
int ret=0;
int i=0;
for(i=0;i<n;i++)
{
printf("Sword attack:%d\n",5);
ret+=5;
}
return ret;
}
int gun(int n)
{
int ret=0;
int i=0;
for(i=0;i<n;i++)
{
printf("Gun attack:%d\n",10);
ret+=10;
}
return ret;
}
int main()
{
fight(knife,5);
fight(sword,5);
fight(gun,5);
return 0;
}
1.fight(wp,arg)函数和knife(n),sword(n),gun(n)他们之间互不依赖,只有当在主函数mian()中调用这3句代码的时候fght(knife,5);fight(sword,5);fight(gun,5);他们之间才通过函数指针产生联系。
(1) 同步回调:把函数b传递给函数a。执行a的时候,回调了b,a要一直等到b执行完才能继续执行;
(2) 异步回调:把函数b传递给函数。执行a的时候,回调了b,然后a就继续往后执行,b独自执行。
实现效果:
代码如下:
// CallbackTest1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// C代码实现的同步回调函数
#include "pch.h"
#include <iostream>
#include<stdio.h>
#include<string.h>
// C函数:回调函数
int RemoteControl(const char *actions[], int actions_len)
{
printf("C回调函数被调用. ==> 你朋友通过你开的 ***远程控制*** 操作你的电脑.\n");
for (int i = 0; i < actions_len; i++)
{
printf(">> %s\n", actions[i]);
}
printf("C回调函数返回. ==> 处理完毕,退出远程的使用.\n");
return 0;
}
// B函数
int YourFriend(int RControl(const char *actions[], int actions_len))
{
// actions是提供的一些动作
const char *actions[] = { "右键计算机",
"选择属性",
"选择高级系统设置",
"... ..."
};
printf("B函数被调用. ==> 你朋友收到你的求助.\n");
RControl(actions, 4); // 回调函数的执行
printf("B函数返回. ==> 你朋友向你反馈处理结果.\n");
return 0;
}
// A函数
int You()
{
printf("A函数启动. ==> 你用电脑,遇到了问题.\n");
printf("A函数调用B函数. ==> 你向你朋友发起求助,同时提供 ***远程控制*** 给他.\n");
YourFriend(RemoteControl);
printf("A函数返回. ==> 你出门办事.\n");
return 0;
}
int main()
{
You();
return 0;
}
异步回调必定是多线程或者多进程的,不可能是单线程或者单进程的。
示例如下:
代码如下:
// CallbackProj.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include<thread>
#include<iostream>
#include<Windows.h>
#include "workThread.h"
using namespace std;
uint32_t OnDoWork(const std::vector<workParam>& vecWorkParam)
{
for (auto pram : vecWorkParam)
{
printf("username:%s \n", pram.username);
printf("time:%d \n", pram.begin_time);
printf("price:%d \n", pram.end_time);
}
return 0;
}
int main(int argc, char *args[])
{
workThread work;
work.GetCallbackData(OnDoWork);
//system("pause");
printf("The main Thread is over! \n");
return 0;
}
子线程类如下:
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include<unordered_map>
#include<thread>
#include<Windows.h>
struct workParam
{
char username[10];
uint32_t begin_time;
uint32_t end_time;
};
typedef uint32_t(*CallFun)(const std::vector<workParam>& vecParam);
class workThread
{
public:
workThread();
~workThread();
static workThread& GetInstance();
void Init();
void OnRun();
void Realese();
uint32_t GetCallbackData(CallFun call_fun);
private:
std::thread m_workThread;
CallFun m_callFun;
std::vector<workParam> m_vecParams;
std::unordered_map<uint32_t, CallFun> m_mapFun;
};
#include "pch.h"
#include "workThread.h"
workThread::workThread()
{
}
workThread::~workThread()
{
Realese();
}
workThread& workThread::GetInstance()
{
static workThread threadImp;
return threadImp;
}
void workThread::Init()
{
workParam params;
strncpy_s(params.username, "000001", sizeof(params.username));
params.begin_time = 12345;
params.end_time = 8888;
m_vecParams.push_back(params);
strncpy_s(params.username, "000002", sizeof(params.username));
params.begin_time = 54454;
params.end_time = 4444;
m_vecParams.push_back(params);
strncpy_s(params.username, "000003", sizeof(params.username));
params.begin_time = 96875;
params.end_time = 6666;
m_vecParams.push_back(params);
m_workThread = std::thread(std::bind(&workThread::OnRun, this));
}
void workThread::OnRun()
{
printf("Child thread start successful! \n");
Sleep(1000);
m_mapFun[1](m_vecParams);
}
void workThread::Realese()
{
if (m_workThread.joinable())
{
m_workThread.join();
}
}
uint32_t workThread::GetCallbackData(CallFun call_fun)
{
Init();
m_mapFun[1] = call_fun;
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。