C++回调实现

本文通过一个示例展示了如何使用回调函数在多线程环境中处理实时股票信息。一个线程负责读取股票数据,读取完成后调用回调函数将结果传递给上级类。回调函数在计算两个数的和后,将结果回传,模拟了实时数据处理的场景。同时,代码中还包含了一个用于日志显示的辅助函数和一个类内的回调测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实际应用场景:

一个线程类读取实时股票信息,在读取完成后,调用回调函数,把读取到的结果返回上级类。

下面的是一个回调示例,两个数相加,在一个线程内运算结果后,通过回调回传计算结果

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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值