세상 살다 보면 별일이 다 발생한다지만 코딩 하다가 발생하는 난감함 중 하나가 사용자(여기서 말하는 사용자는 내가 만든 'dll'이나 클래스 등을 사용하는 사람을 말한다.)가 만든 코드를 호출해야 할 때입니다.
머.... 난감하다는 표현으로 하는 이유는 이런 방식은 내가 개발하고 있는 방향에서 반대로 간다고 생각하기 때문이지 별다른 뜻이 있는 건 아닙니다. ㅎㅎ
(한마디로 심각하게 개인적인 견해라는 말씀)
이런 경우 흔gl 쓰는 방법이 함수 포인터를 이용한 콜백입니다. (CallBack)
(닷넷에서는 델리게이트나 개체를 전달하여 구현 할 수 있죠.)
설명하자면....
1) 클래스(dA) 내부에 사용자가 만든 함수의 포인터(dB)를 저장해둘 변수(?)를 만든다.
2) 사용자가 함수(uF)를 만든다.
3) 사용자는 클래스(uI)를 생성한 후 자신이 만든 함수(uF)를 함수 포인터저장변수(dB)에 넣는다.
4) 클래스(dA) 내부에서 함수 포인터저장변수(dB)를 호출한다.
5) 결과적으로 사용자가 함수(uF)가 호출된다.
그림으로 표현하자면
요렇게 되겠습니다.
내가 만들어서 배포할 프로젝트의 코드입니다.
class dA { public: //함수포인터 저장용 void (*dB) (char *s); //함수 포인터 호출용 void dC(char *a); };
#include "claTest.h" void dA::dC(char *a) { //사용자 함수 호출 dB(a); }
내가 만든 dll을 가져다 쓸 사용자의 프로그램입니다.
void uF(char *s) { int a; a=1; }
//클래스 인스턴스 선언 dA* uI; //클래스 인스턴스 생성 uI = new dA(); //함수 등록 uI->dB = uF; //함수 호출 uI->dC("콜백해서 온거다 냥");
이제 uF에 중단점을 걸고 실행해보겠습니다.
테스트를 위해서 'char*'을 사용했는데 선언한 함수 모양만 맞혀주면 동작합니다.
void (*dB) (char *s, int i);
요런 것도 가능하죠
이 예제 코드에서는 예외 처리가 없습니다.
함수 포인터 저장용 변수를 생성할 때 NULL로 초기화해놓고 널이면 예외 처리를 하던가 하는 방법으로 해주어야 예상치 못한 에러를 막을 수 있습니다.
함수 콜백은 은근이 여기저기서 많이 쓰이니 잘 사용하시길 ㅎㅎ