분류
1. 개요
함수의 호출 실행 시점을 프로그래머가 아닌 시스템에서 결정하는 함수.
2. 예시
Windows API를 예로 들자면
이때 WndProc 함수는 프로그래머가 직접 호출하는 것이 아닌 프로세스에 이벤트가 들어왔을 때 DispatchMessage 함수를 호출하여 이벤트를 처리하며 시스템에서 WndProc를 호출한다. 호출의 주도권을 프로그래머가 아닌 시스템이 쥔다.
이런 콜백함수를 주로 볼 수 있는 경우는 Node.js에서 볼 수 있는데, Node.js의 특성상 비동기처리가 많기 때문에 처리의 결과를 프로그래머가 받기 위해서는 콜백함수를 사용하여 시스템이 결과값을 콜백함수를 호출하여 넘겨주기 때문이다. Node.js는 이게 숱하게 중첩되는 경우가 많아 콜백 지옥이라는 별명까지 붙었을 정도.
예를 들어 pbkdf2는 문자열의 해시를 계산하는 함수이며 그 처리시간이 오래 걸린다. 그 처리시간을 그저 기다리지 말고 다른 작업를 하여 전체 처리 시간을 줄일 수 있다.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass = "First";
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = (WNDPROC)WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,lpszClass, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
while(GetMessage(&Message, 0, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
이때 WndProc 함수는 프로그래머가 직접 호출하는 것이 아닌 프로세스에 이벤트가 들어왔을 때 DispatchMessage 함수를 호출하여 이벤트를 처리하며 시스템에서 WndProc를 호출한다. 호출의 주도권을 프로그래머가 아닌 시스템이 쥔다.
이런 콜백함수를 주로 볼 수 있는 경우는 Node.js에서 볼 수 있는데, Node.js의 특성상 비동기처리가 많기 때문에 처리의 결과를 프로그래머가 받기 위해서는 콜백함수를 사용하여 시스템이 결과값을 콜백함수를 호출하여 넘겨주기 때문이다. Node.js는 이게 숱하게 중첩되는 경우가 많아 콜백 지옥이라는 별명까지 붙었을 정도.
예를 들어 pbkdf2는 문자열의 해시를 계산하는 함수이며 그 처리시간이 오래 걸린다. 그 처리시간을 그저 기다리지 말고 다른 작업를 하여 전체 처리 시간을 줄일 수 있다.
const crypto = require('crypto');
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => {
if (err) throw err;
console.log(key.toString('hex')); // 'c5e478d...1469e50'
});
console.log("main ended.");