C++类成员函数作为回调函数(提供完整工程代码)

本文介绍了在C++中遇到的将成员函数作为回调函数的问题,详细分析了成员函数作为回调函数时遇到的“this”指针问题,以及为何不能直接使用成员函数作为回调。提出了三种解决方案:1) 使用全局函数,2) 将成员函数设为静态,3) 利用std::bind和std::function。并提供了相关工程代码供读者调试和学习。
摘要由CSDN通过智能技术生成

遇见

在我们使用一些第三方SDK、不同框架层之间的事件通知或第三方的C库时,经常需要用相应的接口来注册一些回调函数来处理特定的事件。这里以NOLO SDK为例来描述这样的一个问题。

    typedef enum ExpandMsgType {

      DoubleClickMenu=1,
      DoubleClickSystem
    }ExpandMsgType;

    typedef void(__cdecl *expandMsg_FuncCallBack)(ExpandMsgType expandMsgType);
    NOLO_API  bool _cdecl expandDataNotify_FuncCallBack(expandMsg_FuncCallBack fun);

我们注册一个expandMsg_FuncCallBack类型的回调函数,代码如下:

#include "stdafx.h"
#include <windows.h>
#include "nolo_api.h"
using namespace NOLO;
class HeadMountDevice{
public:
    HeadMountDevice() {};
    ~HeadMountDevice() {};
    void CallBackFunction(ExpandMsgType expandMsgType) {};
};
int main()
{
    HeadMountDevice *p_hmd = new HeadMountDevice();
    expandDataNotify_FuncCallBack(p_hmd->CallBackFunction);
    system("Pause");
    return 0;
}

报错:

 error C3867: 'HeadMountDevice::CallBackFunction': non-standard syntax; use '&' to create a pointer to member

似乎是需要使用’&’来指向成员函数,修改后如下:

#include "stdafx.h"
#include <windows.h>
#include "nolo_api.h"
using namespace NOLO;
class HeadMountDevice{
public:
    HeadMountDevice() {};
    ~HeadMountDevice() {};
    void CallBackFunction(ExpandMsgType expandMsgType) {};
};
int main()
{
    HeadMountDevice *p_hmd = new HeadMountDevice();
    expandDataNotify_FuncCallBack(&p_hmd->CallBackFunction);//modify this line
    system("Pause");
    return 0;
}

还是报错:

error C2276: '&': illegal operation on bound member function expression

使用”&类名::函数名”方式访问成员函数的地址:

...
expandDataNotify_FuncCallBack(&HeadMountDevice::CallBackFunction);
...

依然报错:

error C2664: 'bool NOLO::expandDataNotify_FuncCallBack(NOLO::expandMsg_FuncCallBack)': cannot convert argument 1 from 'void (__thiscall HeadMountDevice::* )(NOLO::ExpandMsgType)' to 'NOLO::expandMsg_FuncCallBack'

分析

这里成员函数作为回调函数,不能通过这种方式来指定,主要原因有两个:
1. 成员函数属于类本身,而不属于任何一个特定的实体.
2. 成员函数默认隐藏了一个”this”指针参数,填充在参数列表的第一个位置,所以你的回调函数与SDK上的回调函数实际上并不匹配!
上面第一点,很容易理解,关

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值