0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言使用回調(diào)函數(shù)模擬委托與反射

STM32嵌入式開發(fā) ? 來源:STM32嵌入式開發(fā) ? 作者:STM32嵌入式開發(fā) ? 2022-03-14 10:19 ? 次閱讀

函數(shù)是C語言的核心概念。主調(diào)函數(shù)(caller)調(diào)用被調(diào)函數(shù)(callee)是一般的調(diào)用關(guān)系,如果被調(diào)函數(shù)(callee)參數(shù)包含函數(shù)指針,函數(shù)指針還可以形成多一層的調(diào)用關(guān)系,形成第三方函數(shù)的調(diào)用,專業(yè)術(shù)語稱為回調(diào)(callback),通過函數(shù)指針參數(shù)調(diào)用的第三方函數(shù)稱為回調(diào)函數(shù)。

回調(diào)可以讓被調(diào)函數(shù)(這里是指用函數(shù)指針做函數(shù)參數(shù)的函數(shù))的代碼更加泛化或抽象,能夠簡(jiǎn)單模擬其它編程語言的委托與反射語法。

1 簡(jiǎn)單模擬委托

//C語言簡(jiǎn)單模擬委托//需要用的指針函數(shù)。通過用指針函數(shù)作為地址接收函數(shù)地址,以達(dá)到委托其他函數(shù)實(shí)現(xiàn)某方法的目的。#include typedef void(* fun)(); //typedef 把void(*)()類型重命名為funvoid func(fun); // 被調(diào)函數(shù)void func_1(); // 回調(diào)函數(shù)1void func_2(); // 回調(diào)函數(shù)2 int main() // 主函數(shù)用做主調(diào)函數(shù){ func(func_1); fun f = func_2; f(); func(func_1); func(func_2); getchar(); return 0;}void func(fun f) //fun f為地址,fun * f為f指向的地址的量或者其他{ printf("func "); if (f != NULL) { f(); }}void func_1(){ printf("func_1 ");}void func_2(){ printf("func_2 ");}/*funcfunc_1func_2funcfunc_1funcfunc_2*/

2 簡(jiǎn)單模擬反射

(1)簡(jiǎn)單模擬反射

高級(jí)語言的反射機(jī)制,簡(jiǎn)單來說,就是可以通過字符串型獲取對(duì)應(yīng)的類或者函數(shù)。下面,用C來簡(jiǎn)單模擬反射:

#include #include typedef void (*callback)(void); typedef struct { const char *name; callback fn;}callback_t; void f0();void f1(); callback_t callbacks[] = { {"cmd0", f0}, {"cmd1", f1},}; void f0() // 回調(diào)函數(shù)0{ printf("cmd0");} void f1() // 回調(diào)函數(shù)1{ printf("cmd1");} void do_callback(const char *name) { size_t i; for (i = 0; i < sizeof(callbacks) / sizeof(callbacks[0]); i++) { if (!strcmp(callbacks[i].name, name)) { callbacks[i].fn(); } }} int main(){ do_callback("cmd1"); getchar(); return 0;}

(2)利用自定義段

gcc支持通過使用 __ attribute __ ((section())),將函數(shù)、變量放到指定的數(shù)據(jù)段中。也就是說,可以讓編譯器幫我們完成上例中向數(shù)組添加成員的動(dòng)作。

借助此機(jī)制,回調(diào)函數(shù)可以在任意文件聲明,不需要修改其他文件。自定義段的起始和結(jié)束地址,可以通過變量 __ start_SECTIONNAME 和 __ stop_SECTIONNAME得到例如通過 __ attribute __ ((section("ss"))定義自定義段,其開始地址為 & __ start_ss,結(jié)束地址為 & __stop_ss。

// https://www.bejson.com/runcode/c920/#include #define SEC __attribute__((__section__("ss"), aligned(sizeof(void*)))) void func_1 (int a, int b){ printf("%s %d %d ", __func__, __LINE__, a+b); }void func_2 (int a, int b){ printf("%s %d %d ", __func__, __LINE__, a*b); } // 編譯器會(huì)自動(dòng)提供__start_ss,__stop_ss標(biāo)志段ss的起止地址extern size_t __start_ss;extern size_t __stop_ss; typedef struct { void (*p)(int, int);} node_t; // 結(jié)構(gòu)體變量a位于自定義段ssSEC node_t a = { .p = func_1, };SEC node_t b = { .p = func_2, };int main(int argc, char **argv){ int a = 3, b = 4; node_t *p; // 遍歷段ss,執(zhí)行node_t結(jié)構(gòu)中的p指向的函數(shù) for (p = (node_t *)&__start_ss; p < (node_t *)&__stop_ss;p++) { p->p(a, b); a+=1;b+=2; }}/*func_1 6 7func_2 10 24 */

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135571
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4259

    瀏覽量

    62228
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1607

    瀏覽量

    48977

原文標(biāo)題:C語言使用回調(diào)函數(shù)模擬委托與反射

文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    請(qǐng)問ESP32C3 I2S驅(qū)動(dòng)支持回調(diào)函數(shù)獲取數(shù)據(jù)嗎?

    目前I2S驅(qū)動(dòng)只看到i2s_read接口獲取數(shù)據(jù),但這是polling方式的。是否有注冊(cè)回調(diào)函數(shù),當(dāng)數(shù)據(jù)到達(dá)是調(diào)用回函數(shù)通知上層app?
    發(fā)表于 06-28 06:11

    為什么無法停止使用cy_wcm_connect 的rtos定時(shí)器回調(diào)函數(shù)?

    。 由于 cy_wcm_connect() 函數(shù)的某些原因,計(jì)時(shí)器無法停止。 取而代之的是調(diào)用回調(diào)函數(shù),由于設(shè)備已連接到 Wifi,它將再次嘗試停止計(jì)時(shí)器。 我想知道如何以正確的方式停
    發(fā)表于 05-24 06:34

    CAPL腳本使用介紹

    CAPL中也有類似于C語言中的回調(diào)函數(shù)的機(jī)制,如檢測(cè)報(bào)文周期和錯(cuò)誤幀的函數(shù)中就可以使用,當(dāng)周期超界或者總線出現(xiàn)錯(cuò)誤幀就會(huì)自動(dòng)調(diào)
    的頭像 發(fā)表于 04-01 11:23 ?1358次閱讀

    調(diào)函數(shù)(callback)是什么?回調(diào)函數(shù)的實(shí)現(xiàn)方法

    調(diào)函數(shù)是一種特殊的函數(shù),它作為參數(shù)傳遞給另一個(gè)函數(shù),并在被調(diào)用函數(shù)執(zhí)行完畢后被調(diào)用?;?b class='flag-5'>調(diào)
    發(fā)表于 03-12 11:46 ?2469次閱讀

    ??嵌入式中回調(diào)函數(shù)的實(shí)現(xiàn)方法

    調(diào)函數(shù)的命名規(guī)范沒有固定的標(biāo)準(zhǔn),但是根據(jù)通用慣例和編碼規(guī)范,回調(diào)函數(shù)的命名應(yīng)該能夠反映函數(shù)的作用和功能,讓其他開發(fā)者能夠快速理解并使用。
    發(fā)表于 03-04 14:49 ?588次閱讀

    如何給C語言中的函數(shù)定義兩個(gè)不同的名字?

    最近有位哥問我,如何給C語言中的函數(shù)定義兩個(gè)不同的名字?就是這兩個(gè)名字都是指向同一個(gè)函數(shù),同一個(gè)地址,而且兩個(gè)名字都可以當(dāng)做函數(shù)來用的那種。
    的頭像 發(fā)表于 12-19 16:21 ?641次閱讀

    c語言函數(shù)函數(shù)體用什么符號(hào)括起來

    函數(shù) 是指將一組能完成一個(gè)功能或多個(gè)功能的語句放在一起的 代碼結(jié)構(gòu) 。 在 C語言程序 中,至少會(huì)包含一個(gè)函數(shù),及主函數(shù)main()。本文將
    的頭像 發(fā)表于 11-24 15:52 ?619次閱讀
    <b class='flag-5'>c</b><b class='flag-5'>語言</b>中<b class='flag-5'>函數(shù)</b>的<b class='flag-5'>函數(shù)</b>體用什么符號(hào)括起來

    C語言printf函數(shù)族學(xué)習(xí)筆記

    printf 應(yīng)該是學(xué)習(xí)C語言的第一個(gè)函數(shù),我們都知道它是用于字符串格式化輸出的。但是它的用法你真正了解了嗎?
    的頭像 發(fā)表于 11-24 11:15 ?835次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>printf<b class='flag-5'>函數(shù)</b>族學(xué)習(xí)筆記

    c語言源程序main函數(shù)的位置

    C語言源程序中的main函數(shù)是程序的入口點(diǎn),它被認(rèn)為是C語言程序的起點(diǎn)。在執(zhí)行程序時(shí),操作系統(tǒng)將首先定位到main
    的頭像 發(fā)表于 11-24 10:23 ?2108次閱讀

    c語言gets函數(shù)可以輸入數(shù)字嗎

    C語言中的gets函數(shù)是用來讀取字符串的,而不是用來讀取數(shù)字的。它會(huì)讀取輸入的字符直到遇到換行符或者文件結(jié)束符。因此,如果你嘗試使用gets函數(shù)來讀取數(shù)字,是無法準(zhǔn)確獲取數(shù)字本身的。
    的頭像 發(fā)表于 11-24 10:00 ?1310次閱讀

    c語言max函數(shù)在哪個(gè)庫

    C語言的max函數(shù)并不屬于標(biāo)準(zhǔn)C庫,它通常是由程序員自己編寫的一個(gè)宏定義。max函數(shù)用于比較兩個(gè)數(shù)的大小,返回較大的數(shù)值。 為了提供更多詳實(shí)
    的頭像 發(fā)表于 11-22 10:18 ?2997次閱讀

    c語言max函數(shù)的使用方法

    C語言是一門廣泛使用的編程語言,提供了許多內(nèi)置的函數(shù)來執(zhí)行各種任務(wù)。其中一個(gè)非常有用的函數(shù)是max函數(shù)
    的頭像 發(fā)表于 11-22 10:15 ?1.2w次閱讀

    淺談C語言面向?qū)ο缶幊趟枷?/a>

    C語言是一種面向過程的語言,但是也可以用結(jié)構(gòu)體和函數(shù)指針來模擬面向?qū)ο蟮奶匦?,比如封裝、繼承和多態(tài)。
    發(fā)表于 11-02 12:27 ?926次閱讀

    如何綁架C語言標(biāo)準(zhǔn)庫函數(shù)?

    C語言動(dòng)態(tài)內(nèi)存可以使用 malloc 標(biāo)準(zhǔn)庫函數(shù),而 C++ 會(huì)使用 new 關(guān)鍵字申請(qǐng),裸機(jī)情況下一般沒有問題,但是在 RTOS 情況下,就需要考慮資源保護(hù)的情況
    發(fā)表于 11-01 09:50 ?301次閱讀

    C語言函數(shù)返回1和返回0究竟哪個(gè)好?

    C語言函數(shù)返回1和返回0究竟哪個(gè)好? 在C語言中,很多函數(shù)需要返回一個(gè)值來表示
    的頭像 發(fā)表于 10-31 14:43 ?878次閱讀