回调函数

本文探讨了在使用第三方SDK时,如何利用Qt的信号与槽机制解决回调函数中的线程安全问题。通过实例演示了如何注册静态回调函数,并在回调中通过信号触发相应的槽函数,实现跨线程的数据安全处理。

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

本次再一次见证Qt信号和槽的强大。下面是所遇所得,分享下。

回调函数,使用需要是static或者全局,即不能对其特指。

  • 使用的情景:经常遇见使用第三方的SDK,需要将我们的回调函数进行注册。
  • 遇到的问题:回调函数中使用非静态成员,即静态成员访问非静态的。
  • 涉及的细节:通常这种回调被第三方工作与其他线程。

首先,关于细节,我们可以将涉及的数据进行拷贝,通过Qt的信号和槽机制,emit出需要处理的数据,关于问题,下面的方法是推荐的。

#ifndef CALLBACKTEST_H
#define CALLBACKTEST_H

#include <QObject>

class CallBackTest : public QObject
{
    Q_OBJECT
public:
    explicit CallBackTest(QObject *parent = nullptr);

    //回调函数
    static int endFrame(QString str, void *ptr);
    static int endWork(int count, void *ptr);

signals:
    void sig_endFrame(QString str);
    void sig_endWork(int count);
    void sig_endWork(QString str);

public slots:

};

// 回调函数是针对某一个对象,故被注册的回调函数是全局,即static或者全局
// 回调函数可能位于其他线程,将要处理的数据进行memcpy,建议通过Qt的信号和槽处理数据,
// 静态函数使用非静态成员,方法1,全局对象,方法2,函数传入对象指针,使用时进行转换即可
// Qt推荐使用的死循环 QEventLoop
#include "callbacktest.h"
#include <QDebug>

typedef int (*endFrame)(QString, void*);
typedef int (*endWork)(int, void*);

void setCallBackFuns(endFrame ef, endWork eW);
void setCallBackFuns(endFrame ef, endWork eW, void* ptr){
    // do some thing
    // loop
    // time to do
    ef("ef", ptr);
    eW(1, ptr);
}

CallBackTest::CallBackTest(QObject *parent) : QObject(parent)
{

    connect(this, &CallBackTest::sig_endFrame, [](QString str){
        qDebug() << "callBack_eF" << str;
    });


    connect(this, static_cast<void(CallBackTest::*)(int)>(&CallBackTest::sig_endWork), [](int count){
        qDebug() << "callBack_eW_int" << count;
    });

    connect(this, static_cast<void(CallBackTest::*)(QString)>(&CallBackTest::sig_endWork), [](QString str){
       qDebug() << "callBack_eW_str" << str;
    });
    // 注册回调
    setCallBackFuns(endFrame, endWork, this);
}

int CallBackTest::endFrame(QString str, void *ptr)
{
    CallBackTest *pThis = static_cast<CallBackTest*>(ptr);
    if(pThis){
        pThis->sig_endFrame(str);
        return 0;
    }
    return -1;
}

int CallBackTest::endWork(int count, void *ptr)
{
    CallBackTest *pThis = static_cast<CallBackTest*>(ptr);
    if(pThis){
        pThis->sig_endWork(count);
        pThis->sig_endWork("endwork");
        return 0;
    }
    return -1;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值