티스토리 뷰

static 멤버 함수가 아닌 일반(비정적) 멤버 함수를 콜백 함수로 사용하는 방법


이때는 this라는 객체의 포인터를 전달해야 한다.

아래는 정적 래퍼 메서드를 만들고 별도의 콜백 파라미터로 this 포인터를 전달하는 방법이다.


[main.cpp]

#include "modulea.h"
#include "moduleb.h"

int main(int, char **)
{
	ModuleB b;
	ModuleA a;
	int     closure = 16;

	b.SetCallback(&a, ModuleA::StaticWrapper, &closure); // 콜백 함수 등록( a 객체의 주소도 함께 전달 )
	b.DoAction(); // 등록된 콜백 함수 호출

	return 0;
}

SetCallback 함수를 보면 첫번째 파라미터에 콜백 함수를 호출할 객체의 주소를 전달한다.

두번째 파라미터는 비정적 함수가 아닌 정적함수 StaticWrapper 주소를 전달한다.

미리 알려드리자면 StaticWrapper 함수내에서 정적 함수를 호출하는 구조이다.


[modulea.h]

#ifndef MODULEA_H
#define MODULEA_H

#include <string>

class ModuleA
{
public:
	static void StaticWrapper(void *obj, const std::string &name, void *data); // 멤버 함수 호출
	void InstanceMethod(const std::string &name, void *data); // 멤버 함수 콜백
};

#endif

콜백 함수가 선언된 ModuleA 클래스 선언부이다.

정적 함수인 StaticWrapper가 있고 비정적 함수인 InstanceMethod가 선언되어 있다.


[modulea.cpp]

#include "modulea.h"
#include <iostream>

using std::cout;
using std::endl;

void ModuleA::StaticWrapper(void *obj, const std::string &name, void *data)
{
	ModuleA *self = (ModuleA *)(obj);
	self->InstanceMethod(name, data);
}

void ModuleA::InstanceMethod(const std::string &name, void *data)
{
	int closure = *(int*)(data);
	cout << "In instance callback: '" << name << "' (closure=" << closure << ")" << endl;
}

StaticWrapper 함수를 보면 전달받은 obj를 ModuleA 객체로 캐스팅하고 그 객체의 멤버 함수를 호출하는 형식이다.


[moduleb.h]

#ifndef MODULEB_H
#define MODULEB_H

#include <string>
#include <stdlib.h>

class ModuleB
{
public:
	typedef void (*CallbackType)(void *obj, const std::string &name, void *data); // 콜백 타입 정의

	ModuleB();

	void SetCallback(void *obj, CallbackType cb, void *data); // 콜백 함수 등록
	void DoAction(); // 콜백 함수 호출

private:
	void         *mObject;
	CallbackType mCallback;
	void         *mClosure;
};

#endif

ModuleB 클래스는 콜백 함수 주소와 대상이 되는 객체(ModuleA) 주소, 사용할 파라미터 값을 관리한다.


[moduleb.cpp]

#include "moduleb.h"

ModuleB::ModuleB() : mObject(NULL), mCallback(NULL), mClosure(NULL)
{
}

void ModuleB::SetCallback(void *obj, CallbackType cb, void *data)
{
	mObject = obj;
	mCallback = cb;
	mClosure = data;
}

void ModuleB::DoAction()
{
	if (mCallback)
	{
		(*mCallback)(mObject, "Hello World", mClosure);
	}
}

DoAction 함수에서 등록된 콜백함수를 호출한다.

'프로그래밍 > 코드' 카테고리의 다른 글

static 멤버 함수를 콜백 함수로 사용  (0) 2018.06.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함