프로그래밍/C++

[C++] 내가 널 위해 함수를 불러주마 - 함수 포인터를 이용한 콜백

당근천국 2011. 7. 11. 03:24

세상 살다 보면 별일이 다 발생한다지만 코딩 하다가 발생하는 난감함 중 하나가 사용자(여기서 말하는 사용자는 내가 만든 'dll'이나 클래스 등을 사용하는 사람을 말한다.)가 만든 코드를 호출해야 할 때입니다.

 

머.... 난감하다는 표현으로 하는 이유는 이런 방식은 내가 개발하고 있는 방향에서 반대로 간다고 생각하기 때문이지 별다른 뜻이 있는 건 아닙니다. ㅎㅎ

(한마디로 심각하게 개인적인 견해라는 말씀)

 

 

1. 함수 포인터 콜백

이런 경우 흔gl 쓰는 방법이 함수 포인터를 이용한 콜백입니다. (CallBack)

(닷넷에서는 델리게이트나 개체를 전달하여 구현 할 수 있죠.)

 

설명하자면....

1) 클래스(dA) 내부에 사용자가 만든 함수의 포인터(dB)를 저장해둘 변수(?)를 만든다.

2) 사용자가 함수(uF)를 만든다.

3) 사용자는 클래스(uI)를 생성한 후 자신이 만든 함수(uF)를 함수 포인터저장변수(dB)에 넣는다.

4) 클래스(dA) 내부에서 함수 포인터저장변수(dB)를 호출한다.

5) 결과적으로 사용자가 함수(uF)가 호출된다.

그림으로 표현하자면

요렇게 되겠습니다.

 

 

1-1. 개발자 프로그램(dll)

내가 만들어서 배포할 프로젝트의 코드입니다.

 

1-1-1. 'claTest.h'
class dA
{
public:
	//함수포인터 저장용
	void (*dB) (char *s);

	//함수 포인터 호출용
	void dC(char *a);
};

 

1-1-2. 'claTest.cpp'
#include "claTest.h"

void dA::dC(char *a)
{

	//사용자 함수 호출
	dB(a);
}

 

 

1-2. 사용자 프로그램(exe)

내가 만든 dll을 가져다 쓸 사용자의 프로그램입니다.

 

1-2-1. 선언부(.h)
void uF(char *s)
{
	int a;
	a=1;
}

 

1-2-2. 클래스 생성 및 호출
//클래스 인스턴스 선언
dA* uI;

//클래스 인스턴스 생성
uI = new dA();

//함수 등록
uI->dB = uF;

//함수 호출
uI->dC("콜백해서 온거다 냥");

 

 

2. 결과 확인

이제 uF에 중단점을 걸고 실행해보겠습니다.

클래스 함수를 호출했으나 사용자 함수가 잘 호출된 모습을 볼수 있다.

 

테스트를 위해서 'char*'을 사용했는데 선언한 함수 모양만 맞혀주면 동작합니다.

 

void (*dB) (char *s, int i);

요런 것도 가능하죠

 

이 예제 코드에서는 예외 처리가 없습니다.

함수 포인터 저장용 변수를 생성할 때 NULL로 초기화해놓고 널이면 예외 처리를 하던가 하는 방법으로 해주어야 예상치 못한 에러를 막을 수 있습니다.

 

 

마무리

함수 콜백은 은근이 여기저기서 많이 쓰이니 잘 사용하시길 ㅎㅎ