c语言callback函数用法,C函数回调(callback)C++类成员函数的方法

本文探讨了C++中如何处理类成员函数回调的困境,介绍了两种解决方案:一是将成员函数声明为静态,避免依赖对象;二是通过传递对象实例,以实现对非静态成员的访问。作者分享了详细的代码示例,并讨论了两种方法的优劣。
摘要由CSDN通过智能技术生成

问题的由来

C回调的步骤一般是:

声明callback函数类型;

根据类型定义一个callback函数A;

把定义的函数A,作为参数传入到另外一个函数B;

函数B会在某个时刻,调用A。

因为C里面函数定义了之后,都是一个全局变量,编译就会分配好地址,所以可以很方便的传递和使用。

但是在C++里,情况有点不一样:

C++的类成员方法即使声明定义了,如果这个类不实例化成对象,那么,类成员方法是不会有地址的,所以也就无法传递给C函数。

简单讲,就是你不能使用一个尚且还不存在东东~

那怎么办呢?

问题的解决

经过摸索,目前总结有两种方法:

一. 类成员函数声明成static函数

类的static成员讲解请看这篇:C++ 类的静态成员详细讲解

声明成static的类成员函数,简单讲,就跟C语言的全局函数是一个意思,编译阶段就确定好了内存地址,不再依赖对象而存在,因此使用起来就跟C函数是一样的,只不过要这样:类名::方法(),要加个前缀。

在VC下的代码如下:

mythread.h

#ifndef _MY_TEST_H_

#define _MY_TEST_H_

class TestClass {

public:

TestClass();

~TestClass();

static void notify(int arg1, int arg2); // declared as static function

private:

void callback();

};

#endif

mythread.cpp:

#include

#include

#include

#include "mythread.h"

typedef void * HANDLE;

#define SEMAPHORE HANDLE

#define THREADHANDLE HANDLE

#define THREADPROCESS DWORD WINAPI

#define THREADRETURN 0

#define PTHREADPROCESS LPTHREAD_START_ROUTINE

#define NULLTHREAD NULL

int g_thread_end = 0;

TestClass::TestClass() {

}

TestClass::~TestClass() {

}

void TestClass::notify(int arg1, int arg2) {

printf("notify() is called!\n");

//callback(); // static function cannot call no-static function

}

void TestClass::callback() {

printf("callback() is called!\n");

}

THREADHANDLE os_creatthread(PTHREADPROCESS fun,void *para)

{

unsigned long id;

return CreateThread(NULL,0,fun,para,0,&id);

}

void waitforthread()

{

while (g_thread_end == 0)

{

NULL;

}

}

typedef void(*testCb)(int arg1, int arg2);

THREADPROCESS threadfun(PVOID arg)

{

int i;

testCb mC;

mC = (testCb)arg;

for(i=0; i < 50; i++)

{

printf("%02d: ", i);

mC(0, 0); // callback is called!

Sleep(500);

}

g_thread_end = 1;

return 0;

}

void main()

{

THREADHANDLE pthread = NULLTHREAD;

printf("Creating thread...\n");

pthread = os_creatthread(threadfun, TestClass::notify); // new a thread and register callback

printf("Creating thread completed.Handle:%x\n", pthread);

printf("Waiting for thread...\n");

waitforthread();

printf("Waiting ended.\n");

}

注释应该写的很清楚了:)

要注意的一点是:

静态函数是无法访问类的非静态成员的

二. 传递对象

基于一切皆对象的观点,既然不能直接传函数,那我们就传对象好了嘛~

请看代码:

mythread.h:

#ifndef _MY_TEST_H_

#define _MY_TEST_H_

class TestClass {

public:

TestClass();

~TestClass();

void notify();

private:

void callback();

};

#endif

mythread.cpp:

#include

#include

#include

#include "mythread.h"

typedef void * HANDLE;

#define SEMAPHORE HANDLE

#define THREADHANDLE HANDLE

#define THREADPROCESS DWORD WINAPI

#define THREADRETURN 0

#define PTHREADPROCESS LPTHREAD_START_ROUTINE

#define NULLTHREAD NULL

int g_thread_end = 0;

TestClass::TestClass() {

}

TestClass::~TestClass() {

}

void TestClass::notify() {

printf("notify() is called! -> ");

callback();

}

void TestClass::callback() {

printf("callback() is called!\n");

}

THREADHANDLE os_creatthread(PTHREADPROCESS fun,void *para)

{

unsigned long id;

return CreateThread(NULL,0,fun,para,0,&id);

}

void waitforthread()

{

while (g_thread_end == 0)

{

NULL;

}

}

THREADPROCESS threadfun(PVOID arg)

{

int i;

TestClass *mC;

mC = (TestClass *)arg;

for(i=0; i < 50; i++)

{

printf("%02d: ", i);

mC->notify(); // callback function is calling

Sleep(500);

}

g_thread_end = 1;

return 0;

}

void main()

{

THREADHANDLE pthread = NULLTHREAD;

TestClass *myClass = new TestClass(); // firstly, new an object

printf("Creating thread...\n");

pthread = os_creatthread(threadfun, myClass); // register this object as callback

printf("Creating thread completed.Handle:%x\n", pthread);

printf("Waiting for thread...\n");

waitforthread();

printf("Waiting ended.\n");

delete myClass;

}

OK,说完了,两种方法哪种更好用,我目前还挺喜欢第二种的,因为没有只能访问静态成员的限制,有了对象之后,你就可以为所欲为啦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值