函數(shù)是C語言的核心概念。主調函數(shù)(caller)調用被調函數(shù)(callee)是一般的調用關系,如果被調函數(shù)(callee)參數(shù)包含函數(shù)指針,函數(shù)指針還可以形成多一層的調用關系,形成第三方函數(shù)的調用,專業(yè)術語稱為回調(callback),通過函數(shù)指針參數(shù)調用的第三方函數(shù)稱為回調函數(shù)。
回調可以讓被調函數(shù)(這里是指用函數(shù)指針做函數(shù)參數(shù)的函數(shù))的代碼更加泛化或抽象,能夠簡單模擬其它編程語言的委托與反射語法。
1、簡單模擬委托
//C語言簡單模擬委托
//需要用的指針函數(shù)。通過用指針函數(shù)作為地址接收函數(shù)地址,以達到委托其他函數(shù)實現(xiàn)某方法的目的。
#include
typedefvoid(*fun)();//typedef把void(*)()類型重命名為fun
voidfunc(fun);//被調函數(shù)
voidfunc_1();//回調函數(shù)1
voidfunc_2();//回調函數(shù)2
intmain()//主函數(shù)用做主調函數(shù)
{
func(func_1);
funf=func_2;
f();
func(func_1);
func(func_2);
getchar();
return0;
}
voidfunc(funf)//funf為地址,fun*f為f指向的地址的量或者其他
{
printf("func
");
if(f!=NULL)
{
f();
}
}
voidfunc_1()
{
printf("func_1
");
}
voidfunc_2()
{
printf("func_2
");
}
/*
func
func_1
func_2
func
func_1
func
func_2
*/
2、簡單模擬反射
(1)簡單模擬反射
高級語言的反射機制,簡單來說,就是可以通過字符串型獲取對應的類或者函數(shù)。下面,用C來簡單模擬反射:
#include
#include
typedefvoid(*callback)(void);
typedefstruct{
constchar*name;
callbackfn;
}callback_t;
voidf0();
voidf1();
callback_tcallbacks[]={
{"cmd0",f0},
{"cmd1",f1},
};
voidf0()//回調函數(shù)0
{
printf("cmd0");
}
voidf1()//回調函數(shù)1
{
printf("cmd1");
}
voiddo_callback(constchar*name)
{
size_ti;
for(i=0;isizeof(callbacks)/sizeof(callbacks[0]);i++){
if(!strcmp(callbacks[i].name,name)){
callbacks[i].fn();
}
}
}
intmain()
{
do_callback("cmd1");
getchar();
return0;
}
(2)利用自定義段
gcc支持通過使用 __ attribute __ ((section())),將函數(shù)、變量放到指定的數(shù)據(jù)段中。也就是說,可以讓編譯器幫我們完成上例中向數(shù)組添加成員的動作。
借助此機制,回調函數(shù)可以在任意文件聲明,不需要修改其他文件。自定義段的起始和結束地址,可以通過變量 __ start_SECTIONNAME 和 __ stop_SECTIONNAME得到例如通過 __ attribute __ ((section("ss"))定義自定義段,其開始地址為 & __ start_ss,結束地址為 & __stop_ss。
//https://www.bejson.com/runcode/c920/
#include
#defineSEC__attribute__((__section__("ss"),aligned(sizeof(void*))))
voidfunc_1(inta,intb)
{
printf("%s%d%d
",__func__,__LINE__,a+b);
}
voidfunc_2(inta,intb)
{
printf("%s%d%d
",__func__,__LINE__,a*b);
}
//編譯器會自動提供__start_ss,__stop_ss標志段ss的起止地址
externsize_t__start_ss;
externsize_t__stop_ss;
typedefstruct{
void(*p)(int,int);
}node_t;
//結構體變量a位于自定義段ss
SECnode_ta={
.p=func_1,
};
SECnode_tb={
.p=func_2,
};
intmain(intargc,char**argv)
{
inta=3,b=4;
node_t*p;
//遍歷段ss,執(zhí)行node_t結構中的p指向的函數(shù)
for(p=(node_t*)&__start_ss;p(node_t*)&__stop_ss;p++){
p->p(a,b);
a+=1;b+=2;
}
}
/*
func_167
func_21024
*/
原文標題:C語言使用回調函數(shù)模擬委托與反射
文章出處:【微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
-
參數(shù)
+關注
關注
11文章
1865瀏覽量
32781 -
C語言
+關注
關注
180文章
7628瀏覽量
139835 -
函數(shù)
+關注
關注
3文章
4365瀏覽量
63912
原文標題:C語言使用回調函數(shù)模擬委托與反射
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
單模光纖-你應該選擇什么樣的?
藍牙單模和雙模的區(qū)別
DigiPCBA 庫遷移系列 - 簡單模式
塔臺模擬機飛行進程單模塊的設計與實現(xiàn)
LOG100的簡單模式對數(shù)放大電路

SIMULINK簡單模型的建立及模型特點
S7-200簡單模擬量編程程序
簡單模擬控制的單相VIENNA整流器研究

評論