2010-05-07 6 views
3

그래서 나는 그들이 어떻게 작동하는지 궁금해하고있었습니다. "함수 호출자"가 의미하는 바를 설명하기 위해 나는 glutTimerFunc이라는 함수를 매개 변수로 취할 수 있으며 선언 된 것을 모른 채 호출 할 수도 있습니다. 어떻게 이러는거야?함수 호출자 (콜백)가 C입니까?

답변

6

당신이 말하는 것은 callback이며 C 및 C++에서는 function pointers으로 구현됩니다.

glut에 대해 언급 했으므로 freeglut 소스 코드에서 직접 실제 예를 들어 봅시다. 코드가 더 간단하기 때문에 glutTimerFunc 대신 glutIdleFunc을 사용합니다.

유휴 함수 콜백 (glutIdleFunc에 제공하는 것)은 매개 변수를 사용하지 않고 아무것도 반환하지 않는 함수에 대한 포인터입니다.

여기
typedef void (* FGCBIdle)(void); 

이 (유휴 FreeGlut 콜백 짧은) FGCBIdle 대가 형 공극 아니 파라미터를 취하지 않는 기능에 대한 포인터로서 정의된다 : 타입 정의는 함수 유형 이름을 지정하는 데 사용된다. 이는 식을 쉽게 작성하고 저장 영역을 할당하지 못하도록하는 형식 정의 일뿐입니다.

Freeglut에는 다양한 설정을 저장하는 SFG_State라는 구조가 있습니다. 그 구조의 정의의 일부는 다음과 같습니다

struct tagSFG_State 
{ 
    /* stuff */ 
    FGCBIdle   IdleCallback;   /* The global idle callback  */ 
    /* stuff */ 
}; 

구조체는 우리가 특정 함수 포인터의 또 다른 이름 설립 형 FGCBIdle의 변수를 보유하고 있습니다. IdleCallback 필드가 glutIdleFunc 함수를 사용하여 사용자가 제공하는 함수의 주소를 가리 키도록 설정할 수 있습니다. 함수의 (단순화 된) 정의는 다음과 같습니다.

void glutIdleFunc(void (* callback)(void)) 
{ 
    fgState.IdleCallback = callback; 
} 

여기서 fgState는 SFG_State 변수입니다. 보시다시피 glutIdleFunc는 하나의 매개 변수를 취합니다.이 매개 변수는 매개 변수를 사용하지 않고 아무 것도 반환하지 않는 함수에 대한 함수 포인터입니다.이 매개 변수의 이름은 콜백입니다. 함수 내에서 전역 fgState 변수의 IdleCallback은 사용자가 제공 한 콜백으로 설정됩니다. glutIdleFunc 함수를 호출하면 자신의 함수 이름 (예 : glutIdleFunc (myIdle))을 전달하지만 실제로 전달하는 것은 함수의 주소입니다. 유휴 콜백 공급 사용자가 사용할 수있는 경우,이 루프에서 호출

if(fgState.IdleCallback) 
{ 
      /* stuff */ 
      fgState.IdleCallback(); 
} 

:

나중에 위해 glutMainLoop에 의해 시작된 큰 과잉 이벤트 처리 루프 내에서, 당신은이 코드를 찾을 수 있습니다. 내 포스트 시작 부분에서 함수 포인터 자습서를 확인하면 구문을 더 잘 이해할 수 있지만 일반적인 개념이 더 이해되기를 바랍니다.

2

매개 변수는 함수에 대한 포인터입니다. 함수 선언이 요구 사항 (예 : 매개 변수의 수와 유형, 호출 규칙)과 일치하는지 확인하는 것은 호출자의 책임입니다.

0

매개 변수로 전달 된 함수는 함수 포인터로 전달됩니다.

컴파일 된 코드에서 함수는 CPU가 실행할 벡터화 할 수있는 주소에 불과합니다. 함수 포인터를 전달할 때 컴파일러 (및 나중에 링커) 올바른 주소를 호출에 삽입합니다.

함수 매개 변수는 실행 코드가 스택 (또는 아키텍처에 따라 레지스터)에 값을 밀어 넣고 반환 값을 팝 아웃 (읽기)하기를 기대하는 것과 정확하게 일치해야합니다.

관련 문제