2010-04-29 37 views
5

Tôi là người mới đến C. Tôi đang cố triển khai chức năng gọi lại bằng cách sử dụng con trỏ hàm.Thực hiện chức năng gọi lại trong C

Tôi nhận được một lỗi

:test_callback.c:10: error: expected identifier or ‘(’ before ‘void’ 

khi tôi cố gắng để biên dịch chương trình sau đây:

#include<stdio.h> 

void (*callback) (void); 

void callback_proc() 
{ 
    printf ("Inside callback function\n"); 
} 

void register ((void (*callback) (void))) 
{ 
    printf ("Inside registration \n"); 
    callback(); /* Calling an initial callback with function pointer */ 
} 

int main() 
{ 
    callback = callback_proc;/* Assigning function to the function pointer */ 
    register (callback);/* Passing the function pointer */ 
    return 0; 
} 

lỗi này là gì có ai có thể giúp?

+0

'đăng ký' là từ khóa, BTW. –

+0

Bạn gặp lỗi trên đường nào? –

+0

Chỉ cần một mẹo: typedefs giúp làm cho mọi thứ dễ đọc hơn một chút: 'typedef void (* CallbackFunc) (void);'. Sau đó, chữ ký hàm của bạn là 'void registerFunc (CallbackFunc callback)' và các khai báo của bạn là 'CallbackFunc my_cb = & callback_proc' – detly

Trả lời

3

tôi sẽ khuyên bạn nên sử dụng một typedef

#include<stdio.h> 

typedef void (*callback_t) (void); 
callback_t callback; 

void callback_proc(void) 
{ 
    printf ("Inside callback function\n"); 
} 

void reg(callback_t _callback) 
{ 
    printf ("Inside registration \n"); 
    _callback(); 
} 

int main() 
{ 
    callback = callback_proc; 
    reg(callback); 

    return 0; 
} 

EDIT: loại bỏ các vấn đề đăng ký

+1

ở đâu là typedef? đó là một đề nghị rất tốt, nhưng ví dụ của bạn là thiếu nó. –

+0

Tôi không thấy typedef? Những gì bạn đã làm được định nghĩa một con trỏ hàm, mà không phải là loại an toàn. –

+0

Xin lỗi đã không nhận ra rằng tôi đã có một vấn đề với sao chép và dán – stacker

2

Bạn không thể sử dụng 'đăng ký' như một tên hàm như đó là một từ khóa C.

19
  1. register là từ khóa C: Sử dụng tên khác cho hàm.

  2. Bạn có thêm các dấu ngoặc xung quanh thông số gọi lại. Nó nên là:

    void funcName(void (*callback) (void)) 
    
+0

Vâng, các parens thêm là khó nắm bắt. +1 –

0

2 vấn đề:

  • bạn không thể sử dụng tên register như đó là một từ khóa (không sử dụng thường xuyên nữa, nhưng nó vẫn còn đó)
  • thay đổi định nghĩa của hàm từ

    void wasRegister((void (*callback) (void))) 
    

    to:

    void wasRegister(void (*callback) (void)) 
    

    (loại bỏ các dấu ngoặc xung quanh khai báo tham số.

Ngoài ra bạn có thể nhận được một cảnh báo về callback_proc() không có một Tờ khai phù hợp để biến callback (tùy thuộc vào cách bạn biên dịch chương trình - như C hay C++), vì vậy bạn có thể muốn thay đổi tuyên bố của mình để:

void callback_proc (void) 

để làm rõ rằng không cần tham số.

0

Hãy xem type safe callbacks từ ccan. Một điều của nó để lộ ra một con trỏ hàm được đánh máy để thế giới sử dụng, một con trỏ khác của nó để đảm bảo việc đúc lành mạnh.

+1

Xin chào, liên kết trong câu trả lời của bạn đã chết. – bummi

+0

@bummi, nếu Tim quyết định xóa câu trả lời này, anh ấy sẽ nhận được một tin nhắn * Bài đăng này đã bị xóa bởi Tim Post ♦. Để biết tại sao câu trả lời của bạn bị xóa, hãy sử dụng meta *: D –

0
#include<stdio.h> 

typedef void (*callback_func) (void); 

static callback_func the_callback = 0; 

void process (void) 
{ 
    printf ("Inside process function\n"); 
} 

void callback_register (callback_func cb) 
{ 
    the_callback = cb; 
    printf ("Inside registration \n"); 
} 

void callback(void) 
{ 
    the_callback(); 
} 

int main (void) 
{ 
    callback_register(process); /* Passing the function pointer */ 
    callback(); 
    return 0; 
} 

Tuyên bố the_callback tĩnh sẽ có ý nghĩa hơn nếu mã này là module và sau đó bạn sẽ buộc phải gọi callback_register để thiết lập nó, và callback để gọi nó - the_callback sẽ không được bên ngoài truy cập của thực hiện (.c) chỉ các khai báo hàm sẽ nằm trong tiêu đề (.h).

+0

cảm ơn rất nhiều ... tôi có thể hiểu được những sai lầm của tôi – user329013

Các vấn đề liên quan