简单的回调函数使用与创建

一般回调函数使用场景:
主线程需要等待某个事件触发再同时立刻触发某个操作。例如:
主控制器循环监控当前场景是否有车辆进入,当进入时,触发某个操作。此操作在我们调用线程中实现。
代码示例:
回调函数线程:
头文件:

#pragma once
#include "iostream"

using namespace std;
// 定义跨平台
#ifdef _WIN32
#define TE_VIDEO_API extern "C" __declspec(dllexport)
#else
#define TE_VIDEO_API extern "C"
#endif

typedef void* TE_HANDLE;
// 定义函数指针类型
typedef int(*PFN_OnDisplayCallback)(TE_HANDLE hDevice, char *pBuffer, int nBuffLen, void *pUserData);
// 主线程执行体
TE_VIDEO_API TE_HANDLE TEStartWork(TE_HANDLE handle);
// 注册回调函数
TE_VIDEO_API TE_HANDLE TE_RegisterCallback(PFN_OnDisplayCallback pfnDisplayCallback, void* param);
// 反注册回调函数
TE_VIDEO_API TE_HANDLE TE_UnRegisterCallback();

cpp文件

#include "iostream"
#include "windows.h"
#include "test.h"

using namespace std;

PFN_OnDisplayCallback g_pfnCallBack;
void* g_pParam;
DWORD WINAPI ThreadDone(PVOID param)
{
    ***while (true)
    {
        if (g_pfnCallBack != NULL)
        {
            if (/*发生事件*/)
            {
                // 执行传入的函数指针。
                g_pfnCallBack(NULL, NULL, 0, g_pParam);
            }
        }
    }***
}
//  功能的主要执行模块,需要第一个调用,用于创建循环体
TE_VIDEO_API TE_HANDLE TEStartWork(TE_HANDLE handle)
{
    g_pfnCallBack = NULL;
    g_pParam = NULL;
    /*
    暂时为了程序,使用windows自带的创建线程机制。如果为了跨平台,请使用跨平台库
    */
    LPDWORD pThread;
    HANDLE hThread = (NULL, 0, ThreadDone, NULL, CREATE_SUSPENDED, pThread);
    ResumeThread(hThread);
}
// 用于注册回调函数
TE_VIDEO_API TE_HANDLE TE_RegisterCallback(PFN_OnDisplayCallback pfnDisplayCallback, void* param)
{
    if (pfnDisplayCallback != NULL)
    {
        g_pfnCallBack = pfnDisplayCallback;
        g_pParam = param;
    }
}
// 用于删除回调函数
TE_VIDEO_API TE_HANDLE TE_UnRegisterCallback()
{
    pfnDisplayCallback = NULL;
}

接下来需要调用上述的导出函数:

// 将上述的头文件加上
#include "test.h"
#include "iostream"

using namespace std;
// 定义一个同样类型的回调函数
PFN_OnDisplayCallback procCB(TE_HANDLE hDevice, char *pBuffer, int nBuffLen, void *pUserData)
{
    // 执行获取到数据之后的操作
}

int main()
{
    TEStartWork(NULL);

    TE_RegisterCallback(procCB, NULL);

    Sleep(10000);

    TE_UnRegisterCallback();
}

至此,一个简单的回调函数实现方式已经结束了。
注意:回调函数体一定要是全局函数或者静态成员函数(一样的道理)。因此,线程的安全性就有了问题。所以在加入参数时,一定要分清时哪一个线程触发的事件。以后有机会再讲。

猜你喜欢

转载自blog.csdn.net/baidu_24388023/article/details/81462782