第一部分 基本的回调函数写
// callback.cpp : 定义控制台应用程序的入口点。
// 回调函数就是一个通过函数指针调用的函数
//
#include "stdafx.h"
#include <iostream>
void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule1 = "<< schedule <<std::endl;
std::cout<<"str1 = "<< str <<std::endl;
}
void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule2 = "<< schedule <<std::endl;
std::cout<<"str2 = "<< str <<std::endl;
}
// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码
typedef void (*mCallback)(int schedule, char* str); // 定义一个指向函数的函数指针
void caller(mCallback p) // 在main中调用的形式(mian直接调用);p是一个指针
{ // 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
// 具体的操作有最终传到p的函数决定
(*p)(1, "xxvvc456cs89cs-cs");
}
int _tmain(int argc, _TCHAR* argv[])
{
caller(&OutputSchedule1);
caller(&OutputSchedule2);
return 0;
}
第二部分 类中的回调函数写法
// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 写法一
#include "stdafx.h"
#include <iostream>
class mClass
{
public:
// 类中包含的是两个函数的实现过程
void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule1 = "<< schedule <<std::endl;
std::cout<<"str1 = "<< str <<std::endl;
}
void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule2 = "<< schedule <<std::endl;
std::cout<<"str2 = "<< str <<std::endl;
}
};
// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码
typedef void (mClass::*pMenberFunction)(int schedule, char* str); // 声明的符合‘类成员类型’的函数指针
void caller(mClass* pObj ,pMenberFunction p) // 在main中调用的形式(mian直接调用);p是一个指针;pObj最终用于传递类对象
{ // 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
// 具体的操作有最终传到p的函数决定
(pObj->*p)(1, "xxvvc456cs89cs-cs");
}
int _tmain(int argc, _TCHAR* argv[])
{
mClass mItem;
caller(&mItem, &mClass::OutputSchedule1); // 第二个参数p接受的变量是函数指针,注意是使用类中定义的函数名(类似泛称),而非(确定的某一个)mItem的成员
caller(&mItem, &mClass::OutputSchedule2);
return 0;
}
// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 写法二 使用模板
#include "stdafx.h"
#include <iostream>
class mClass
{
public:
// 类中包含的是两个函数的实现过程
void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule1 = "<< schedule <<std::endl;
std::cout<<"str1 = "<< str <<std::endl;
}
void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
std::cout<<"schedule2 = "<< schedule <<std::endl;
std::cout<<"str2 = "<< str <<std::endl;
}
};
// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码
template<typename T> // !!仅修改此处及下下行,使用template:T 来替换类名:mClass
// 这样,就不局限为某一个类。只要类成员的形式满足 void xxx(int, char*) 就可以使用这个callback函数:caller
void caller(T* pObj, void(T::*p)(int schedule, char* str))// 在main中调用的形式(mian直接调用);p是一个指针;pObj最终用于传递类对象
{ // 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
// 具体的操作有最终传到p的函数决定
(pObj->*p)(1, "xxvvc456cs89cs-cs");
}
int _tmain(int argc, _TCHAR* argv[])
{
mClass mItem;
caller(&mItem, &mClass::OutputSchedule1); // 第二个参数p接受的变量是函数指针,注意是使用类中定义的函数名(类似泛称),而非(确定的某一个)mItem的成员
caller(&mItem, &mClass::OutputSchedule2);
return 0;
}
第三部分 类中调用回调函数,在调用者一方编写操作内容(比如可用于进度值回调)
// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 在类(或dll)中传值到main
// 比如:可以用于进度回调
//
#include "stdafx.h"
#include <iostream>
class mClass
{
public:
typedef void(*mScheduleCallback)(int schedule, char* str);
void caller(mScheduleCallback p) // 在类(dll)中传递两个参数(int schedule, char* str 亦即 1, "xxvvc456cs89cs-cs")给调用者
{ // 传递出去的了两个参数的用途由调用者编写的函数决定
p(1, "xxvvc456cs89cs-cs"); // 比如可以作为进度值回调给调用者
}
};
// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码
void OutputSchedule1(int schedule, char* str) // 有调用者编写的函数指针指向的本体,也就是此处的两个参数的显示操作(main间接调用)
{
std::cout<<"schedule1 = "<< schedule <<std::endl;
std::cout<<"str1 = "<< str <<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
mClass mItem;
mItem.caller(&OutputSchedule1); // 有无引用符号好像都可以,这个测试代码还看不出差异
return 0;
}