[C++] 내가 널 위해 함수를 불러주마 - 함수 포인터를 이용한 콜백
세상 살다 보면 별일이 다 발생한다지만 코딩 하다가 발생하는 난감함 중 하나가 사용자(여기서 말하는 사용자는 내가 만든 '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로 초기화해놓고 널이면 예외 처리를 하던가 하는 방법으로 해주어야 예상치 못한 에러를 막을 수 있습니다.
마무리
함수 콜백은 은근이 여기저기서 많이 쓰이니 잘 사용하시길 ㅎㅎ