C 언어 - CallBack함수(콜백함수)

컴퓨터/C

728x90
반응형

CallBack함수란 무엇인가?

인터넷을 통해 콜백 함수에 대해 찾아보면 다양한 말로 엄청나게 많은 설명이 있습니다.

피호 출자가 호출자에게 요청하는 함수..

암시적 호출을 하는 함수.. 호출되는 함수.. 

간단하게 콜백 함수라 불리는 녀석들은 C언어에서는 함수 포인터가 매개변수로 들어가는 함수를 콜백 함수라 일컫습니다.

 

그렇다면 왜 함수포인터를 매개변수로 사용하는가?

그럼 여러 글들에서 설명하는 것처럼 함수 포인터를 매개변수로 사용하는 함수를 왜 콜백 함수라는 이름을 만들어서 부르고 있는 건지 알 필요가 있습니다.

함수 포인터를 이용하면 똑같은 형식의 함수의 메모리 주소를 참조할 수 있게 됩니다.

 

그렇다면, 아래의 가정을 들어 예를 들어보도록 합시다.

  • A라는 프로그래머가 sum이라는 함수를 만들었다.
  • 이 sum은 두 매개변수를 받아 더한 값을 반환한다. 
  • 이 함수를 라이브러리 형태로 배포하였다.
  • B 프로그래머가 해당 라이브러리에서 sum을 사용했다. 
  • 잘 사용하던 도중 B 프로그래머는 두 매개변수의 절댓값을 받아 더하는 기능을 사용하고 싶다.

위와 같은 상황에서 함수 포인터를 이용한 함수 즉 콜백 함수가 존재하지 않는다면 B의 요청에 의해 A프로그래머는 새로운 기능을 가진 함수를 만들고 배포해야 됩니다. 

이 과정에서 극단적인 괴리가 생기게 됩니다. 

A프로그래머는 한 명의 사용자를 위해 다시 만들고 배포를 해야 되며, B는 A가 다시 만들어 줄 때까지 하염없이 기다려야 됩니다.

이런 과정을 극복하게 해주는 녀석이 바로 콜백 함수입니다. 

그럼 예제 소스를 보며 이해를 해보겠습니다.

 

  • 함수 포인터를 사용하지 않는 경우
int sum(int a, int b) {
	return a + b;
}
int sum_abs(int a, int b) {

	if (a < 0) a = a * -1;
	if (b < 0) b = b * -1;

	return a + b;
}

예제처럼 계속해서 새로운 기능을 담는 함수를 만들거나, 수정하여 배포하여야 됩니다. 

하지만 콜백 함수의 개념을 도입하면 상황이 바뀌게 됩니다.

 

  • 콜백 함수를 사용한 경우
//A가 배포한 라이브러리 함수 
//실제 소스코드는 B는 볼수 없음
//다만 A가 콜백을 구현 할 수 있도록 만듬 
int sum(int a, int b, void (*funcp)(int*,int*)) {

	if (funcp != NULL) {
		funcp(&a, &b);
	}

	return a + b;
}

//B가 만든 사용자 정의 함수 콜백용으로 만든 함수
void userdefine(int* a, int* b) {
	if (*a < 0) *a = *a * -1;
	if (*b < 0) *b = *b * -1;
}


int main() {

	int result = 0;

	result = sum(2, -2, NULL);
	printf("콜백 함수 없이 호출 한 결과 : %d \n", result);

	result = sum(2, -2, userdefine);
	printf("콜백 함수를 정의하여 호출 한 결과 : %d\n", result);

	return 0;
}

어느 정도 이해가 되는지 모르겠습니다. 위 소스코드를 해석해보자면 다음과 같습니다.

  • A가 제공한 라이브러리 소스코드는 이렇게 전달될 것입니다.
  • sum이라는 함수를 만들었고 매개변수는 3개로 정수 a, b 그리고 함수 포인터(void funcp(int*,int*))를 제공
  • 기본 기능은 a+b이지만, 원한다면 B가 함수 포인터를 이용해 써!
int sum(int a, int b, void (*funcp)(int*,int*));

라며 라이브러리를 배포했습니다. 

하지만 B는 두 개의 값을 절대 값으로 만들고 더하는 기능을 만들고 싶었습니다. 그래서 자기의 함수를 만들고 그 함수를 A의 라이브러리 매개변수로 이용하여 사용했습니다.

  • B는 자신이 원하는 기능을 A라이브러리 매개변수 규격에 맞게 만들었다.
  • 이후 A가 만든 라이브러리의 sum함수를 호출할 때 매개변수로 B가 만든 함수의 주소를 넣어주었다.
  • 그러자 B는 자신이 만든 함수를 직접 호출하지 않았지만 함수가 동작하여 원하는 기능을 만들 수 있었다.

이게 바로 콜백 함수다.

결국 B는 자신이 함수를 만들었지만 함수를 호출하지 않았습니다. 하지만 어디선가 함수가 동작했고, 원하는 결과를 얻었습니다. 

다시 말하자면 A가 만든 sum이 호출되면서, 매개변수인 함수 포인터를 통해 사용자 B가 아닌 sum을 통해 B가 만든 함수가 호출되었습니다. 이런 것처럼 피호 출자가 함수를 호출하는 녀석을 콜백 함수라고 합니다.

 

꼭 써야되나 ?

꼭 쓰지는 않아도 됩니다. 하지만 위의 예시처럼 콜백의 기능은 A와 B처럼 양쪽에 좋은 점이 많습니다. 그러므로 많이 사용되고 있습니다. 

이 말인즉슨 다른 라이브러리를 사용하는데 콜백에 대한 개념이 자리잡지 않고서는 콜백의 개념을 적용한 라이브러리를 사용하기는 쉽지 않다는 말이 됩니다.

그렇기 때문에 콜백에 대한 개념을 알아두고, 다양한 응용 프로그래밍을 하던 콜백의 개념이 나왔을 때 이해에 도움이 됐으면 합니다.

 

 

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :