2016-02-02 4 views
0

Этот вопрос находится где-то между теоретическим и практическим.Назначение функции обратного вызова в C++

У меня есть файл C (назовем его fileA.c и fileA.h)

fileA.h определяет-структуру как таковую:

typedef struct 
{ 
    /** Callback function which is called upon an event occurrence */ 
    void (*FileAcb)(MyEvent event, uint8 val); 
} MyStruct; 

В fileB.cpp и fileB.h, Я пытаюсь назначить ему функцию обратного вызова следующим образом.

FileB.h

class FileB 
{ 
    public: 
     static void Callback(MyEvent event, uint8 val); 
    protected: 
     /**Protected members */ 
    private: 
     /**Private members */ 
     MyStruct myStruct; 
}; 

FileB.cpp

bool FileB::Start() 
{ 
    myStruct.FileAcb= FileB::Callback; 

    return true; 
} 

void FileB::Callback(MyEvent event, uint8 val) 
{ 
    //do some stuff here. 
} 

И это работает. Тем не менее, я ищу способ, чтобы написать эту строку:

myStruct.FileAcb= FileB::Callback; 

таким образом, что позволяет мой FILEB :: функцию обратного вызова НЕ быть статическим. Есть ли способ достичь этого?

+0

«У меня есть файл C (давайте назовем его fileA.c и fileA.h)» - в зависимости от того, считаете ли вы заголовки как C-файлы (в смысле «язык C») или нет, это либо делает два Файлы C или один не имеют отношения к делу. Во всяком случае, это не C! – Olaf

+0

@ Олаф Я предполагаю, что в этой ситуации я дал постороннюю информацию. В конечном счете, все, о чем я забочусь, это структура typedef в FileA.h. –

+0

Вы искали в Интернете о своем вопросе? ^^ https://www.google.de/search?q=cpp+Callback+function+to+NOT+be+static.&ie=utf-8&oe=utf-8&gws_rd=cr&ei=_MiwVtqYF4fcO6f4s8gM –

ответ

1

Есть ли способ достичь этого?

Не напрямую. Традиционный способ C-стиль, чтобы сделать это, чтобы обеспечить void* аргумент, указывающий на объект, и немного функции переадресации:

struct CallbackWithData 
{ 
    void *closure; 
    void (*callback)(void *closure, MyEvent event, uint8 val); 
}; 

void ForwardToFileB(void *closure, MyEvent event, uint8 val) 
{ 
    FileB *target = (FileB *)closure; 
    target->Callback(event, val); 
} 

Даже в не ОО-стиле C, это традиционное для обеспечения такого рода аргумента для функций обратного вызова, поэтому они должны где-то сохранять какое-либо состояние, в котором они могут нуждаться.

C++ - подобный способ сделать это будет использовать std::function<void(MyEvent,uint8_t)> вместо необработанного указателя.

Смежные вопросы