2011-11-11 3 views
2

함수 포인터 선언과 혼동합니다. 내가 그 API에 인수로 제 기능을 전달하려는 경우어떻게 함수를 C에서 함수 포인터로 사용하도록 선언합니까?

void abc(void (*my_func)(void *p), int, int) 

, 내 .H 파일에 선언하고있다 :

그래서 같은 인수를 취하는 API를 abc()

void (*xyz)(void *p) 

과 같이 정의 :

void *(xyz)(void *p){ 
statements; 
} 

을하지만, 이것은 에러가 발생. 제발 고쳐주세요.

답변

4

당신은 단지 그것을 선언해야합니다 구현에

void xyz(void *p); 

같은 방법으로.

당신이 당신의 API로 전달

는, 타입 시스템은 자동으로 그것을 파악 :

abc(xyz,someint,anotherint); 
3

(*xyz)는 함수 포인터 것을 의미한다.

함수 포인터는 typedef으로 처리하는 것이 가장 좋습니다. 따라서 아무 문제가 없다는 것이 보장됩니다.

// define a type for the function (not its pointers, as you can often read) 
typedef void my_func_t(void *p); 

void abc(my_func_t*, int, int); 

// declaration in order to be type-safe - impossible if only the pointer would be typedef'd 
my_func_t my_func_impl; 

// definition: 
void my_func_impl(void *p) 
{ 
    do_something_with(p); 
} 

을 그리고 당신은 abc(my_func_impl, 47, 11)abc()를 호출 할 수

나는 다음을 수행합니다. my_func_impl 앞에 &을 붙이면 얻을 수있는 기능 주소라는 것을 지적 할 수 있지만 선택 사항입니다.

대안은

typedef void (*my_func_p)(void *p); 

를 작성하고 my_func_t * 대신 my_func_p를 사용하는 것입니다, 그러나 이것은 당신이 my_func_t my_func_impl;을 쓸 수없는 단점이있다.

왜 그렇게하고 싶습니까?

글쎄, 우연이나 사고로 함수 정의 또는이 typedef가 변경되면 더 이상 일치하지 않지만 충돌은 경고로 표시되지 않고 경고 (불일치 포인터)로만 표시됩니다. . OTOH, my_func_t my_func_impl;은 프로토 타입의 일종으로 기능 오류 헤더가 일치하지 않아 오류가 발생합니다.

+1

저는 이것을 typedef void (* my_func_ptr) (void *);로 더 자주 보았습니다. –

+1

네, 나도. 하지만 'my_func_t my_func_impl;'을 사용한이 트릭은 더 이상 가능하지 않습니다. 내가 편집 할게. – glglgl

+0

불쾌감은 없지만, 나 자신을 포함한 많은 프로그래머는'my_func_t my_func_impl; '을보고 전역 변수라고 생각하고 아마도 함수 포인터라고 생각합니다. 그것은 프로그래머가 아닌 컴퓨터를위한 좋은 예입니다. 이와 같은 트릭은 [리눅스 커널의 typedef에 대한 엄격한 제한] (http://www.kernel.org/doc/Documentation/CodingStyle) (5 장, "Typedefs")을 초래했습니다. –

0

'ABC'의 첫 번째 인수는 함수의 포인터가 '무효'반환 및 인수로 '무효 *'가진 ...

그래서 코드가 보일 것입니다 같은 :

void 
myFunc (void *) 
{ 
    // ... my statements 
} 

... 

abc (myFunc, 10, 20); 
1

제가 올바르게 이해했다면, xyzabc으로 전달되는 기능이 되길 원합니다, 맞습니까?

void xyz(void *p); 

그리고 : 인수 my_func 알 수 있듯이

, 당신은 인수로 void *를 받아 void

type (*func_pointer)(type, type, type, .......) 
^^ ^ ^ ^ ^
    | |  |  |  |  | 
    | |  |  argument types 
    | | pointer name 
    | This is a function pointer 
return type 

따라서, 당신은 같은 xyz를 선언 할 필요가 반환하는 함수에 대한 포인터를 가지고 구현시 동일 :

void xyz(void *p){ 
    statements; 
} 

당신이 잘못하고있는 것은 .h 파일에 작성한 줄이 xyz이라는 함수 포인터를 정의한다는 것입니다. 당신이 소스 파일에 쓴 무엇 xyz = some_function;

도 입력으로 void *을 취하고 void *를 반환 이름 xyz으로, 함수 쓴 적이 있기 때문에 함수 포인터 대신 의도였다 void의, 값이 없습니다 .

당신이 int *x; 쓰기, xint에 대한 포인터입니다 :

은 어쩌면 이것은 당신이 덜 혼란스러워 할 수 있습니다. 그런 다음 int y;*이없고 x = &y;을 쓸 수 있습니다.

기능과 동일합니다. void (*funcptr)(void *p);이있는 경우 void some_func(void *p){} (다시 *을 다시 쓰지 않음)이라는 함수가 필요하고 funcptr = some_func;을 작성하십시오. 함수 이름이 실제로 함수의 포인터이기 때문에 &이 필요하지 않습니다. 당신은 그것을 더 명백하게 표현할 수 있습니다.

void xyz(void *p); 

void xyz(void *p){ 
    // ... 
} 

와는 API에 대한 포인터를 전달합니다 : 적절한

abc(xyz, 42, 7); 

함수 이름이 자동으로 함수 포인터로 해석됩니다 당신이 다른 것처럼

+0

이것이 최고의 대답이라고 생각합니다. 이 문제의 근본 원인을 명확하게 설명합니다. 매우 도움이된다! 감사. –

1

간단하게 선언하고 함수를 정의합니다.

abc(&xyz, 42, 7); 
0

void abc(void* (*my_func)(void*), int a, int b) { 
    my_func(0); 
} 

void *(xyz)(void *p) {} 

int main() { 
    abc(xyz, 0, 0); 
    return 0; 
} 

작동이 void (*my_func)(void *p)를 작성하는 경우가 무효 과를 반환 함수에 대한 포인터를 의미 : 간결은 당신의 일이 아니다 경우에도 명시 적으로 함수의 주소를 취할 수 void (*my_func)(void *p) 그것은 포인터를 반환하는 포인터를 의미합니다.

관련 문제