프로그래밍임베디드 C 개발자

C 언어에서 콜백 함수가 어떻게 구현되고 작동하는지 설명하십시오. 라이브러리를 개발하거나 API와 상호 작용할 때 이러한 함수를 올바르게 선언하고 사용하는 방법은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

콜백 함수는 다른 함수의 인수로서 전달되는 함수의 주소입니다. 이를 통해 이벤트 핸들러, 사용자 알고리즘 및 플러그인을 구현할 수 있습니다.

콜백 함수 선언:

  1. 해당 함수 포인터 유형을 정의합니다:
typedef void (*callback_func_t)(int);
  1. 핸들러 함수 전달:
void process(callback_func_t cb) { // ... cb(42); // 콜백 호출 } void handler(int n) { printf("처리된 숫자: %d ", n); } int main() { process(handler); return 0; }

팁:

  • 명시적인 typedef를 사용하여 포인터 유형을 정리하면 코드 가독성이 향상됩니다.
  • 콜백 함수의 시그니처가 예상되는 것과 일치하는지 확인하십시오.
  • 초기화되지 않았거나 해제된 로컬 함수를 전달하지 않도록 하십시오.

함정 질문

식별자가 일치하지 않는 시그니처의 함수를 콜백으로 전달할 수 있습니까?

자주 있는 잘못된 답변: "예, C는 명시적인 형 변환을 선언하면 허용합니다."

올바른 답변: 형식적 형 변환이 가능하긴 하지만, 그러한 함수를 호출하면 정의되지 않은 동작이 발생할 수 있습니다. 매개변수에 잘못된 값이 전달되고 스택이 손상될 수 있습니다.

위험 예:

typedef void (*cb_t)(int); void wrong_cb(double d) { printf("%f ", d); } void call(cb_t f) { f(123); } int main() { call((cb_t)wrong_cb); } // 위험: 시그니처가 다릅니다.

이 주제에 대한 미숙지로 인한 실제 오류 사례


이야기

하나의 임베디드 프로젝트에서 정렬 함수는 너무 좁은 시그니처의 함수 포인터를 compare 함수로 받아들였습니다. 이로 인해 잘못된 매개변수 전달로 인한 정렬 오류와 메모리 손상이 발생했습니다.

이야기

그래픽 엔진의 라이브러리에 콜백을 기반으로 한 이벤트 메커니즘이 구현되었으나, 일부 콜백이 이미 해제된 동적 라이브러리의 로컬 함수에 우연히 참조되었고, 이로 인해 유효하지 않은 주소와 마주쳤을 때 크래시가 발생했습니다.

이야기

크로스 플랫폼 시스템을 개발할 때 작성자는 콜백 함수에 대한 호출 규칙을 잘못 정의했습니다. 이는 한 운영 체제에서는 문제가 발생하지 않았으나, 다른 운영 체제에서 C 라이브러리로부터 콜백을 호출할 때 프로그램이 크래시 되는 결과를 초래했습니다.