实际应用场景:
一个线程类读取实时股票信息,在读取完成后,调用回调函数,把读取到的结果返回上级类。
下面的是一个回调示例,两个数相加,在一个线程内运算结果后,通过回调回传计算结果
CBTest.h
//CBTest.h
//本示例演示了回调函数实现,在入口程序设置相关参数和回调函数后
//用一个线程进行运算,得到结果后通过回调函数,回传运算结果
#pragma once
#include <Windows.h>
class CBTest
{
//声明回调函数,
//sum运算结果回传, p目标类指针
typedef void(CALLBACK *CBFunc)(int sum, void* p);
typedef CBFunc CBHandler;
public:
CBTest();
virtual ~CBTest();
//运算,并设置回调相关信息
void Op(int a, int b, CBFunc handler, void* p);
//检测是否正在运作
bool IsRuning();
private:
//void SetRunning(bool running);
//进行运算的线程
static DWORD CALLBACK ThreadOp(LPVOID p);
void Calculate();
private:
bool mNeedOp;
int a;
int b;
HANDLE mThreadOp;
HANDLE mMutex;
//缓存回调函数指针
CBHandler mCBHandler;
void* mCBObj;
};
CBTest.cpp
//CBTest.cpp
#include "CBTest.h"
CBTest::CBTest()
{
mNeedOp = false;
a = 0;
b = 0;
mThreadOp = INVALID_HANDLE_VALUE;
mMutex = CreateMutexA(NULL, false, "CBTestMutex");
mCBHandler = NULL;
mCBObj = NULL;
//创建线程
LPDWORD p = NULL;
mThreadOp = CreateThread(NULL, 0, ThreadOp, this, 0, p);
}
CBTest::~CBTest()
{
if (mThreadOp != INVALID_HANDLE_VALUE)
{
CloseHandle(mThreadOp);
mThreadOp = INVALID_HANDLE_VALUE;
}
mCBHandler = NULL;
mCBObj = NULL;
}
void CBTest::Op(int a, int b, CBFunc handler, void* p)
{
WaitForSingleObject(mMutex, INFINITE);
this->a = a;
this->b = b;
//缓存回调函数
mCBHandler = handler;
mCBObj = p;
mNeedOp = true;
ReleaseMutex(mMutex);
}
bool CBTest::IsRuning()
{
bool op = false;
//Mutex演示
WaitForSingleObject(mMutex, INFINITE);
op = mNeedOp;
ReleaseMutex(mMutex);
return op;
}
//
//void CBTest::SetRunning(bool running)
//{
// WaitForSingleObject(mMutex, INFINITE);
// mNeedOp = running;
// ReleaseMutex(mMutex);
//}
DWORD CALLBACK CBTest::ThreadOp(LPVOID p)
{
CBTest* test = (CBTest*)p;
while (true)
{
test->Calculate();
}
}
void CBTest::Calculate()
{
if (!IsRuning())
{
Sleep(5);
return;
}
//故意做的一个延时
Sleep(1000);
int sum = a + b;
if (mCBHandler != NULL)
{
(*mCBHandler)(sum, mCBObj);
}
WaitForSingleObject(mMutex, INFINITE);
mNeedOp = false;
ReleaseMutex(mMutex);
}
Main.cpp
//Main.cpp
#include <cstdio>
#include <windows.h>
#include <string>
#include "CBTest.h"
//////////////////////////////////////////////////////////////////////////
//多个参数拼合成一个std::string
std::string format(const char *format, ...)
{
char ret[512] = { 0 };
va_list argptr;
va_start(argptr, format);
vsprintf_s(ret, format, argptr);
va_end(argptr);
return ret;
}
//Log显示函数,显示有输出时间
void LogShow(const char* str, ...)
{
if (str == NULL || strlen(str) == 0)
{
return;
}
SYSTEMTIME sys;
GetLocalTime(&sys);
char ret[512] = { 0 };
va_list argptr;
va_start(argptr, str);
vsprintf_s(ret, str, argptr);
va_end(argptr);
int strLen = strlen(ret);
char change[256] = { 0 };
char retText[256] = { 0 };
int index = 0;
while (index < strLen && index < 256)
{
if (ret[index] == '\n')
{
change[index] = '\n';
}
else
{
if (strLen - index>0)
{
strcpy_s(retText, ret + index);
}
break;
}
index++;
}
std::string retStr;
if (strlen(change) > 0)
{
retStr = format("%s%d/%d/%d %02d:%02d:%02d:%03d %s\n", change, sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds, retText);
}
else
{
retStr = format("%d/%d/%d %02d:%02d:%02d:%03d %s\n", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds, ret);
}
printf(retStr.c_str());
}
//////////////////////////////////////////////////////////////////////////
//回调函数为一个单独的函数
static void CALLBACK ShowResult(int sum, void* p)
{
LogShow("结果是:%i\n", sum);
}
//类中回调测试
class Test
{
public:
void Cal(int a, int b)
{
mCBTest.Op(a, b, &Test::cb, this);
}
bool IsRunning()
{
return mCBTest.IsRuning();
}
private:
static void CALLBACK cb(int sum, void* self)
{
Test* test = (Test*)self;
test->Show(sum);
}
void Show(int sum)
{
LogShow("Test结果是:%i\n", sum);
}
private:
CBTest mCBTest;
};
void main()
{
//注:test与下面的t会分别创建运算线程,
CBTest test;
//单独函数的回调
test.Op(3, 4, &ShowResult, NULL);
Test t;
while (t.IsRunning())
{
Sleep(10);
}
//类中函数的回调
t.Cal(10, 12);
for (int i = 0; i < 100; i++)
{
while (t.IsRunning())
{
Sleep(20);
}
int a = i;
int b = 0;
t.Cal(a, b);
}
char c = 0;
scanf_s("%i", c);
}