c++回调函数创建与使用

构建一个工作类及封装启动它的函数如下:
工作者头文件 “EventWorker.h”

#pragma once
#include <string>
using namespace std;
#define  WORKER_HANDLE	int

enum class WORK_STATUS
{
	FAILED = 0,
	SUCCEED = 1,
	WORKING = 2,
	OTHER
};

struct WORDDONE_CALLBACK_PARAM
{
public:
	void* pUserParam;  //使用者对象指针
	string szWorkerName; //工作者
	string szWorkData;	//工作完成返回的数据
	WORDDONE_CALLBACK_PARAM()
	{
		pUserParam = NULL;
		szWorkerName = "";
		szWorkData = "";
	}
};

typedef void(_stdcall* DoWorkCallBack) (WORDDONE_CALLBACK_PARAM* pUserParam);

WORK_STATUS InitWorker(string szWorkName, WORKER_HANDLE* phOutWorkerHandle);
WORK_STATUS ReleaseWorker(WORKER_HANDLE hWorkerHandle);

WORK_STATUS StartWork(WORKER_HANDLE hWorkerHandle, void* pUserParam, DoWorkCallBack callBackFun);
WORK_STATUS StopWork(WORKER_HANDLE hWorkerHandle);
 

工作者源文件 “EventWorker.cpp”

#include "EventWorker.h"
#include <Windows.h>
#include <sstream>
#include <map>
#include <iostream>

class Worker
{
private:
	string m_szName;
	string m_workData;
	bool m_bStartWork;
	bool m_bIsRunning;
	WORDDONE_CALLBACK_PARAM m_callBackParam;
	DoWorkCallBack m_callBackFun;
public:
	Worker()
	{
		m_szName = "";
		m_workData = "";
		m_bStartWork = false;
		m_bIsRunning = false;
		m_callBackFun = NULL;
	}
	Worker(string szName)
	{
		m_szName = szName;
		m_workData = "";
		m_bStartWork = false;
		m_bIsRunning = false;
		m_callBackFun = NULL;
	}
	void SetName(string szName)
	{
		m_szName = szName;
	}
	string GetName()
	{
		return m_szName;
	}
	void SetCallBackParam(DoWorkCallBack callBackFun, void* pUserParam)
	{
		m_callBackParam.pUserParam = pUserParam;
		m_callBackFun = callBackFun;
	}
	void StartWork()
	{
		m_bStartWork = true;
		while (m_bStartWork)
		{
			m_bIsRunning = true;
			stringstream ss;
			ss << 100 * rand();
			m_workData = ss.str();
			m_callBackParam.szWorkerName = this->m_szName;
			m_callBackParam.szWorkData = this->m_workData;
			if (m_callBackFun)
			{
				m_callBackFun(&m_callBackParam); //回调事件
			}
			Sleep(6000);
		}	
		m_bIsRunning = false;
	}

	void StopWork()
	{
		m_bStartWork = false;
		while (m_bIsRunning)
		{
			Sleep(10);
		}
	}
};

map<int, Worker> m_workerArray;

WORK_STATUS InitWorker(string szWorkName, WORKER_HANDLE* phOutWorkerHandle)
{
	int iWorkHandle = 0;
	bool bExistWorker = false;
	map<int, Worker>::iterator iter;
	for (iter = m_workerArray.begin(); iter != m_workerArray.end(); iter++)
	{
		if (szWorkName == iter->second.GetName())
		{
			bExistWorker = true;
			iWorkHandle = iter->first;
			break;
		}
	}
	
	if (!bExistWorker)
	{
		Worker newWorker(szWorkName);
		while (m_workerArray.find(iWorkHandle) != m_workerArray.end())
		{
			iWorkHandle++; //独一无二的句柄
		}		 
		m_workerArray[iWorkHandle] = newWorker; 
	}	

	*phOutWorkerHandle = iWorkHandle;	 
	return WORK_STATUS::SUCCEED;
}

WORK_STATUS ReleaseWorker(WORKER_HANDLE hWorkerHandle)
{
	if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
	{
		m_workerArray[hWorkerHandle].StopWork();		 
		m_workerArray.erase(hWorkerHandle);
	}
	return WORK_STATUS::SUCCEED;
}

DWORD WINAPI DoWorking_Task(void* arg)
{
	Worker* pWorker = (Worker*)arg;
	if (pWorker)
	{
		pWorker->StartWork();
	}

	return 0;
}

WORK_STATUS StartWork(WORKER_HANDLE hWorkerHandle, void* pUserParam, DoWorkCallBack callBackFun)
{
	WORK_STATUS workStatus = WORK_STATUS::FAILED;
	if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
	{
		m_workerArray[hWorkerHandle].SetCallBackParam(callBackFun, pUserParam);
		HANDLE handle = ::CreateThread(NULL, 0, DoWorking_Task, (void*)&m_workerArray[hWorkerHandle], 0, NULL);
		::CloseHandle(handle);

		workStatus = WORK_STATUS::SUCCEED;
	}
	return workStatus;
}

WORK_STATUS StopWork(WORKER_HANDLE hWorkerHandle)
{
	WORK_STATUS workStatus = WORK_STATUS::FAILED;
	if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
	{
		m_workerArray[hWorkerHandle].StopWork(); 		
		workStatus = WORK_STATUS::SUCCEED;
	}
	return workStatus;
}

测试这个工作者类:

#include "EventWorker.h"
#include <cstring>
#include <iostream>
using namespace std;
//工作的回调函数
static void _stdcall CallBackWorkFun(WORDDONE_CALLBACK_PARAM* pUserParam)
{
    cout << "worker: " << pUserParam->szWorkerName << " is working, work-data: " << pUserParam->szWorkData << endl;
}

int main()
{
    cout << "Hello, please follow the instructions below to Do work!\n";
	cout << "Enter 'NEW[worker-Name]' to build a new worker\n";
	cout << "it will back a handle number like 0,1,2.. which use to start work by enter 'START[0]','START[1]'.. \n";
    cout << "and stop work by enter 'STOP[0]','STOP[1]'..\n";
    cout << "Enter'EXIT' to exit program, Just Go!\n";

GOTO_LABEL_START: //开始位置

    string szText;
    cin >> szText;
	if (szText == "EXIT") return 0;
    else if (szText.find("NEW")!= string::npos)
    {
		int iHandle;
		int startIndex = szText.find("[") + 1;
		int endIndex = szText.find("]");
		if (startIndex != string::npos && endIndex != string::npos)
		{
			string szName = szText.substr(startIndex, endIndex - startIndex);
			if (InitWorker(szName, &iHandle) == WORK_STATUS::SUCCEED)
			{
				cout << "worker: " << szText << " Success. " << "worker handle = " << iHandle << endl;
				bool bStartWork = false;
				while (true)
				{
					cin >> szText;
					if (szText == "EXIT") break;

					if (szText.find("START") != string::npos)
					{
						cout << "StartWork.\n";
						startIndex = szText.find("[") +1;
						endIndex = szText.find("]");
						if (startIndex != string::npos && endIndex != string::npos)
						{
							string szHandle = szText.substr(startIndex, endIndex - startIndex);
							int ilHandle = atoi(szHandle.c_str());
							WORK_STATUS workStatus = StartWork(ilHandle, NULL, CallBackWorkFun); //如果在类中操作,可将类指针对象传入pUserParam
							bStartWork = workStatus == WORK_STATUS::SUCCEED;
						}
					}
					else if (bStartWork && szText.find("STOP") != string::npos)
					{
						startIndex = szText.find("[") +1;
						endIndex = szText.find("]");

						if (startIndex != string::npos && endIndex != string::npos)
						{
							string szHandle = szText.substr(startIndex, endIndex - startIndex);
							int ilHandle = atoi(szHandle.c_str());
							StopWork(ilHandle);
							cout << "StopWork.\n";
						}
					}
					else
					{
						cout << "commad is error, please retry.\n";
					}

				}
			}
			else
			{
				cout << "worker: " << szText << " Failed. " << endl;
				goto GOTO_LABEL_START; //这里只是演示使用,实际项目不建议大家使用goto语句
			}
		}
		
		
    }
    
	return 0;
}

在这里插入图片描述

备注: 测试案例只是简单构建一个对象来演示使用这个工作者类,实际可以操作建立更多对象工作.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农的砖块

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值