把C++类成员方法直接作为线程回调函数

五种将c++类的成员函数用作回调函数的方法——史上最全、最简!!! 前言 在写ROS的cpp代码时发现回调函数十分的常用,然后初学的时候没有深入研究过,记录下几种用法,据说在写线程的时候也很常用。方法五应该是最简单实用的了… 方法一 先从最简单的入手,直接使用普通函数用作回调函数。 #include "pch.h" #include <iostream> using namespace std; class TestCallback { public:... 阅读详情
 

把C++类成员方法直接作为线程回调函数

原文链接:http://blog.youkuaiyun.com/waiting4you/article/details/2000796

我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 

类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类:
class TMyClass{
    void Func();
};

这个TMyClass::Func最终会转化成 void Func(TMyClass *this); 也就是说在原第一个参数前插入指向对象本身的this指针。

我们可以利用这个特性写一个非静态类成员方法来直接作为线程回调函数,先看_beginthread函数的定义:
unsigned long _RTLENTRY _EXPFUNC _beginthread (void (_USERENTRY *__start)(void *),unsigned __stksize, void *__arg);
其中的第一个参数就是作为线程执行主体的回调函数。它的原型是:void Func(void *),这个void*参数是作为自定义数据传入的。对比一下上面所说的TMyClass::Func的最终形式,它正好可以符合这里的要求。

现在做个实验:
#include <stdio.h>
#include <process.h>

class TMyClass{
    int m_nCount;
    int m_nId;
public:
    TMyClass(int nId,int nCount)
        :m_nId(nId),m_nCount(nCount)
    {
    }

    void _USERENTRY ThreadProc()            // 类成员方法
    {
        for(int i=0; i<m_nCount; i++)       // 根据m_nCount成员打印一排数字
        {
            printf("Class%d : %d/n",m_nId,i);
        }
    }
};

int main(int argc, char* argv[])
{
    union {                                // 联合类,用于转换类成员方法指针到普通函数指针(试过编译器不允许在这两种函数之间强制转换),不知道有没有更好的方法。
        void (_USERENTRY *ThreadProc)(void *);
        void (_USERENTRY TMyClass::*MemberProc)();
    } Proc;                                // 尽管联合里的两种函数类型现在看起来有很大不同,但它们的最终形式是相同的。

    TMyClass MyClass1(1,10),MyClass2(2,5); // 产生两个TMyClass对象

    Proc.MemberProc = &TMyClass::ThreadProc;   // 转换,Proc.ThreadProc就是对应的普通函数指针了

    _beginthread(Proc.ThreadProc,4096,&MyClass1);   // 开始线程,这里的Proc.ThreadProc实际上是TMyClass::ThreadProc, 它要的this指针是我们给的&MyClass1。
    _beginthread(Proc.ThreadProc,4096,&MyClass2);
    system("pause");
    return 0;
}

运行!神奇吧?:-)

其实不止线程回调函数,其实只要是形如Func(void*,...)的回调函数都可以用这种方法直接使用类成员方法。(前提是第一个void*是自定义数据,也就是说它不能有其它功能)。

<Zhuuu_ZZ>HIVE(十一)函数 Hive内置函数一 Hive函数分类二 字符函数二 类型转换函数和数学函数三 日期函数四 集合函数五 条件函数六 聚合函数和表生成函数6.1 聚合函数6.2 表生成函数:输出可以作为表使用 一 Hive函数分类 从输入输出角度分类 标准函数:一行数据中的一列或多列为输入,结果为单一值 聚合函数:多行的零列到多列为输入,结果为单一值 表生成函数:零个或多个输入,结果为多列或多行 从实现方式分类 内置函数 自定义函数 UDF:自定义标准函数 UDAF:自定义聚合函数 UDTF:自定义表生成函数 阅读详情

相关推荐

[C++]利用类的回调函数将一个类中的函数变为一个线程

回调函数就是一个通过函数指针调用的函数。我们在进行一些操作时需要实时获取,某些类的状态信息,这时候用回调函数就十分的方便了。 下面简单介绍一下,主类的函数接受其他类的线程回调(表述的有点不清,还是看代码吧) 头文件 //MyFun.h文件 #include <stdlib.h> #include <windows.h> #pragma ...

PangCoder的博客 1949

类成员函数作为回调函数的方法及注意点

编程中遇到一个错误,提示为error C2597: illegal reference to non-static member 即因为一个类的静态成员函数调用了类的非静态成员变量,而报错。 下面具体介绍一些相关知识点,以防下次再出错。 类成员函数当回调函数的方法 参考自:https://blog.youkuaiyun.com/this_capslock/article/details/1700100...

hanxiucaolss的博客 1万+

MIPI DPHY接口(基于Xilinx FPGA实现)案例分析

在Xilinx FPGA实现MIPI DPHY接口的案例(包括CIS协议层)。截止目前为止,Xilinx仅在Ultrascale+及其以上版本的FPGA IO可直接支持MIPI 电平输入,其他的,都需要转换成LVDS来接收。

ONEFPGA的博客 5624

linux 类成员函数 线程函数 arg,把C++类成员方法直接作为线程回调函数

我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:)类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类:class TMyClass{void Func();};这个TMyClass::Func最终会转化成 ...

weixin_29447621的博客 349

STM32H7 FOC控制时序优化与PWM中点更新策略

在永磁同步电机(PMSM)的磁场定向控制(FOC)系统中,控制时序精度是决定电流环带宽、观测器收敛性与动态响应能力的基础要素。其核心在于理解PWM生成、ADC采样与控制计算三者之间的硬件级时间耦合关系——尤其在中心对齐模式下,标准更新机制引入的半周期延迟会破坏电压-电流瞬时映射,导致滑模观测器失配与高频相位滞后。通过将PWM更新事件绑定至重复计数器(RCR)清零点,可实现控制指令在开关周期中点生效,使等效电压矢量中心与计算时刻严格对齐。该策略显著提升系统确定性,为20 kHz以上高频电流环提供物理支撑,并广

flink9streamer的博客 857

Visual Studio调试时遇到ntdll.dll的PDB文件缺失?别慌,这3个方法帮你搞定(附详细步骤)

本文详细解析了Visual Studio调试时ntdll.dll的PDB文件缺失问题,提供了3种实用解决方案:调整调试设置、配置符号服务器与缓存目录、手动下载管理符号文件。通过分步指导和高级技巧,帮助开发者快速恢复完整的调试功能,特别适用于Windows平台下的C++项目开发。

weixin_42537919的博客 513

把C++类成员方法直接作为线程回调函数[转]

我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类:class TMyClass{    void Func();};这个TMyClass::

狂人山庄 1367

WSL2+Docker+Ollama:解锁Windows本地GPU加速运行DeepSeek-R1模型

本文详细介绍了在Windows系统上,通过WSL2、Docker和Ollama的组合方案,实现本地GPU加速运行DeepSeek-R1模型的全过程。该方案解决了Windows环境下Ollama默认无法调用NVIDIA显卡的痛点,通过配置Docker的GPU支持,强制将计算任务分配给GPU,从而显著提升文本生成速度与效率,为开发者提供了一个便捷的本地AI测试环境。

weixin_28452161的博客 356

java线程的入口函数_类成员函数作为多线程的入口函数的实现方法 | 学步园

多线程函数的实现(本例中每次线程被调用的时候均对计数器加1)DWORD WINAPI CMutilThread(LPVOID){CMutilThread *pDlg = (CMutilThread*)lpParam;//定义指向本类的指针,相当于thispDlg->couter++; //计数器加1}多线程函数的创建void CMutiThread::OnStart(){hThrea...

weixin_28730927的博客 205

软件需求规格说明书(SRS)深入解析

摘要: SRS(软件需求规格说明书)是定义系统功能、性能与接口的核心文档,为开发、测试、项目管理提供依据。标准结构包括引言、总体描述、功能/非功能需求、接口等模块。撰写需确保清晰、可验证、无歧义,避免模糊术语。示例展示学生注册模块的需求写法,强调性能与安全性要求。推荐使用Confluence、StarUML等工具辅助编写,交付时需包含主文档、原型图及需求跟踪矩阵。SRS应兼具技术性与管理性,作为沟通桥梁和验收标准。

moton2017的博客 2917

材料仿真软件:Quantum Espresso_(15).声子与振动模式计算

通过上述步骤和代码示例,您应该能够使用 Quantum Espresso 进行声子与振动模式的计算。声子计算是材料科学研究中的重要工具,可以帮助我们更好地理解和设计材料的性能。希望本节内容对您有所帮助。

kkchenjj的博客 1177

C++中 线程函数为静态函数 及 类成员函数作为回调函数(转载)

C++中 线程函数为静态函数 及 类成员函数作为回调函数 线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只是起了一个装饰的作用,所以二者并没有必然的关系 线程也是一种资源,是受系统调度的。因此,你必须要让系统知道你的线程的起始位置,即线程函数的指针。Window系统的接口(API)是C标准的,系统在启动线程时,需要直接得到线程的起始位置,因此你也必须向系统直

Garden的博客 1271

知识存储之Apache Jena

知识图谱的存储可以分为基于表结构的存储和基于图结构的存储。1️⃣基于表结构的存储基于表结构的存储利用二维的数据表对知识图谱中的数据进行存储。根据不同的设计原则,知识图谱可以具有不同的表结构:💨知识图谱实质上是一个个的三元组,一种简单直接的存储方式是设计一张三元组表用于存储所有三元组,有不少比较成熟的产品利用该形式存储知识图谱,包括Jena、Oracle、Virtuoso等。💨为每种类型构建一张表,同一类型的实例存放在相同的表中。

Puzzle的博客 6064

把C++的类的方法直接作为线程的回调函数

把C++的类的方法直接作为线程的回调函数 无意间看见一篇关于线程的好文章,收藏了,出处在文章下面。 以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyCl...

蜗牛也是牛 285

Vue3 - 详细实现调用浏览器摄像头拍照并生成图片预览,支持将抓拍的图像保存到用户本地或上传到服务器、调取前置摄像头和后置摄像头,开启摄像头并进行拍照,vue实现调用摄像头,电脑或手机调用摄像头拍照

vue3,nuxt3,摄像头,vue3网站打开摄像头拍照,vue3项目调用摄像头实现拍照功能,拍照后怎么保存,照相后上传到后端服务器,开启摄像头黑屏,如何默认后置摄像头,网页开启电脑摄像头并照相,前置拍照,vue3如何调用手机摄像头进行拍摄,拒绝权限后不再弹出了,微信公众号网页,摄像头报错,拍照左右镜像反了,浏览器不兼容怎么办,vue3调用电脑端摄像头实时拍照,解决调用摄像头权限无法弹出,打不开摄像头,Vue3如何调用手机的摄像头,调用本地摄像头实现拍照,浏览器不弹摄像头权限了,如何不使用https运行测试

🏆 前端领域优质创作者 8653

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++通过Swig跨线程回调Python代码

无意间看见一篇关于线程的好文章,收藏了,出处在文章下面。 以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类: class TMyClass{ void Func(); }; 这个TMyClass::Func最终会转化成 void Func(TMyCla..

木牛的博客 530

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

c++类成员函数作为回调函数

我以前写线程时要么老老实实照着声明写,要么使用C++类的静态成员函数来作为回调函数,经常会因为线程代码而破坏封装.之前虽然知道类成员函数的展开形式,但从没想过利用过它,昨天看深入ATL时无意中学会了这一招:) 类成员方法是一个比较特殊的函数,它在编译时会被转化成普通函数,比如有TMyClass类: class TMyClass{ view source print?

1009

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

c++ 类 线程函数使用

C++中 线程函数为静态函数 及 类成员函数作为回调函数  线程函数为静态函数:   线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只是起了一个装饰的作用,所以二者并没有必然的关系   线程也是一种资源,是受系统调度的。因此,你必须要让系统知道你的线程的起始位置,...

salman的博客 2291
上一篇: How to create a Windows can run top of Metro UI under windows8c
下一篇: 老罗的锤子砸了王自如的评测
killcpp
博客等级 码龄20年 13粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值