注冊回調的作用
在設計模式中注冊回調的方式叫做回調模式。在SDK開發中,為增強開發者的SDK通用性,排序或者一些算法邏輯需要使用者進行編寫。這時候就需要向SDK傳遞回調函數。
注冊回調能使下層主動與上層通信。從而避免了上層不停詢問下層的模式。
注冊回調的流程
SDK的接口會提供一個注冊回調函數,來規范回調函數的格式,如返回值,參數等。使用者編寫一個固定格式的回調函數,來調用SDK提供的注冊回調函數。當然,在c中注冊回調的實現方式是通過函數指針,在c++中可以通過function和bind實現。
例1
這是一個簡單的函數調用,假設print()是sdk中的api,我們直接使用時候。
#include<iostream> #include<cstdio> using namespace std; void print(string str); //----------使用者模塊----------------- int main() { print("hello word"); system("pause"); return 0; } //----------SDK模塊----------------- void print(string str) { printf(str.c_str()); }
例子2
這次使用函數指針,來間接調用
#include<iostream> #include<cstdio> using namespace std; void print(string str); //----------使用者模塊----------------- int main() { void(*p) (string str); p = print; p("hello word"); system("pause"); return 0; } //----------SDK模塊----------------- void print(string str) { printf(str.c_str()); }
例子3
這就是一個簡單的回調模式。sdk提供注冊回調函數,使用者提供回調函數。
#include<iostream> #include<cstdio> using namespace std; typedef void(*P)(string s); //使用函數指針通常先typedef P p = nullptr; //sdk模塊創建函數指針對象 void print(string str); //使用者模塊創建回調函數 void print_test(string, P p); //注冊回調函數 //----------使用者模塊----------------- int main() { print_test("hello word", print); system("pause"); return 0; } //----------回調函數---------- void print(string str) { printf(str.c_str()); printf("隨便寫"); } //----------SDK模塊----------------- void print_test(string str, P prin)//注冊回調函數 { p = prin; p(str); }
例子4
當然 在實際使用中,與上層通信的函數是常常放在一個線程循環中,等待事件響應,所以通信的函數是不能和注冊函數寫在一起,不能在通信函數中傳入函數指針。需要單獨注冊。
//sdk.h typedef void(*REC_CALLBACK)(long,char *,char *,char *);//調用函數格式 REC_CALLBACK record_callback;//創建實例 //.cpp int register_callback(REC_CALLBACK P)//注冊回調函數 { rec_callback = P; rec_callback_state = true; return 0; } init_record() { while(true) { .......... if (rec_callback1_state==true) { rec_callback(card, time, card_io, state);//調用回調函數 } else { } } }
使用者模塊
print(long,char *,char *,char *)//回調函數 { printf("xxxxx"long ,char......); } int main() { register_callback(print)//使用前先注冊 std::thread t1(init_record); t1.join(); }