當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式微處理器
[導(dǎo)讀]很多人在用 printf 函數(shù)進(jìn)行串口打印的時候,都會被告知需要重定向 fputc 函數(shù)(別的平臺可能不是這個函數(shù)),讓字符串?dāng)?shù)據(jù)輸出到指定串口,按照網(wǎng)上的教程也能很快解決。但是卻沒人告訴你為什么可以被重定向,為什么明明使用的是 printf 函數(shù),重定向的卻是

很多人在用 printf 函數(shù)進(jìn)行串口打印的時候,都會被告知需要重定向 fputc 函數(shù)(別的平臺可能不是這個函數(shù)),讓字符串?dāng)?shù)據(jù)輸出到指定串口,按照網(wǎng)上的教程也能很快解決。但是卻沒人告訴你為什么可以被重定向,為什么明明使用的是 printf 函數(shù),重定向的卻是 fputc 函數(shù)?

使用 51 的時候,我們也可以使用 printf 函數(shù),但是我們并沒有進(jìn)行重定向,也能使用,這又是為什么?

對于經(jīng)驗豐富的人來說,這些問題心里應(yīng)該都有答案,但考慮到有一些道友可能并不了解,所以今天就稍微水那么一篇吧。

這些問題從大一到大三,一直困惑著魚鷹,直到魚鷹在代碼中看到這么個東西:

__attribute__((weak))  //  注意兩個括號

魚鷹一看,沒見過啊,不懂啊,所以魚鷹趕緊去網(wǎng)上查了一下,不查不要緊,一查嚇一跳,發(fā)現(xiàn) __attribute__ 這個東東了不得啊,很多C語言屬性都能修改,功能實在是太強大了,強大到魚鷹自認(rèn)為掌握得不錯的C語言都還只是基礎(chǔ),也就只配在小白面前嘚瑟一下。

言歸正傳,為了突出重點,今天只講 weak 屬性,以防分心。

我們都知道,函數(shù)名不可以重名,當(dāng)然不同文件內(nèi)聲明的 static 函數(shù)倒是可以解除該限制(可查看《C語言之static》)。

但是如果沒有使用 static ,那么編譯器就會給你報錯,告訴你函數(shù)名重復(fù)咯。

編譯器一共告訴你兩個信息:

1、重復(fù)的函數(shù)名是 func_name

2、重復(fù)的地方在 board.c 和 main.c 文件里面(后面 .o 表示目標(biāo)文件,由對應(yīng)的 .c 文件生成)

編譯器一發(fā)出這樣的信息,程序員很快就能找到問題并解決,所以看懂編譯信息很重要(如果有些編譯信息不常見,復(fù)制這條信息到網(wǎng)上一搜,一大堆文章就冒出來了)。

根據(jù)錯誤信息,只要修改一處變量名,即可消除該錯誤。

那么這個和printf重定向有什么關(guān)系?

我們知道,printf 最終會調(diào)用 fputc 進(jìn)行字符串輸出,但是這些函數(shù)是標(biāo)準(zhǔn)庫提供的,而標(biāo)準(zhǔn)庫沒有提供源碼給你,當(dāng)你需要用的時候添加 <stdio.h> 即可。

但是很多時候,fputc 輸出的位置可能需要改變,比如輸出到 LCD、串口1、串口2,我們總不可能去修改標(biāo)準(zhǔn)庫的源碼吧,但也沒有源碼提供啊,怎么才能在不修改源碼的情況下滿足這個需求呢?

方法是有的,比如你可以通過某個函數(shù)向printf中注冊一個回調(diào)函數(shù),讓printf調(diào)用這個回調(diào)函數(shù)進(jìn)行字符串輸出即可,但是標(biāo)準(zhǔn)庫并沒有提供這個東西,因為它用了更好的方式解決這個問題。

那就是本文的主角,符號屬性弱化,weak。

假設(shè)我們拿到了標(biāo)準(zhǔn)庫的源碼,能清楚的看到實現(xiàn)原理,那么我們應(yīng)該能看到一個fputc的函數(shù)。然后你通過分析原理,發(fā)現(xiàn)它的輸出位置不是自己想要的,那么你會怎么做?

既然有源碼,好辦,直接修改fputc的實現(xiàn)即可,簡單。

但現(xiàn)在沒有源碼,怎么辦?但你發(fā)現(xiàn)你在自己的文件里面直接實現(xiàn)fputc函數(shù)好像也沒事,為什么?就是因為標(biāo)準(zhǔn)庫將fputc函數(shù)的屬性進(jìn)行了弱化,即:

這樣做有什么好處?

1、別人可以不需要給你源碼

2、即使沒有源碼,也能間接的達(dá)到修改源碼的目的

3、即使有源碼,通過該屬性設(shè)置,也不需要刪除別人的代碼去重新實現(xiàn),可以保留原來的代碼。

4、不需要使用回調(diào)函數(shù)的方式進(jìn)行注冊,可以直接重新實現(xiàn)該函數(shù),非常簡單

5、存在一個默認(rèn)函數(shù)實現(xiàn),如果說你不想重新實現(xiàn)函數(shù),那么編譯器就會使用該函數(shù)進(jìn)行編譯、鏈接,而不會在編譯時出現(xiàn)錯誤或警告(這就是為什么即使你沒有重新寫一個fputc,編譯也不會報錯的原因)

當(dāng)然,第五點,既是好處也是壞處,因為編譯器沒有提示,你就不知道你到底有沒有重新實現(xiàn)函數(shù)了。

其實要查看編譯器鏈接的到底是哪一個函數(shù)很簡單,打開map文件(關(guān)注了這么久,怎么打開的就不多說了),搜索對應(yīng)的函數(shù)名即可:

你會發(fā)現(xiàn),雖然 main.c 文件中雖然也有一個 func_name 函數(shù),但實際上,編譯器鏈接的是 board.c 文件的,原因就是因為 main.c 文件的 func_name 函數(shù)屬性被弱化了。

這樣一來,即使函數(shù) func_name 在 main() 函數(shù)中被調(diào)用,但它沒有使用本文件的func_name,而是調(diào)用了 board.c 文件中的函數(shù)。

但你將 board.c 文件中的函數(shù)刪掉后,編譯后并不會出現(xiàn)錯誤,并且會發(fā)現(xiàn) main() 調(diào)用的函數(shù)變成了 main.c 文件中的函數(shù)。

就是這么奇妙!

事實上,這個屬性弱化不僅僅在 printf 函數(shù)中體現(xiàn)了,在中斷處理函數(shù)中也做了這樣的處理,只不過這是匯編方式:

這就是為什么你可以在任何文件內(nèi)寫中斷處理函數(shù),而即使你沒有寫中斷處理函數(shù),編譯器也不會報錯的原因!

當(dāng)然了,這種屬性設(shè)置雖然可以保證不同文件的函數(shù)名可以相同(同一個文件的函數(shù)名還是不可以相同),但是最終只有一個函數(shù)會被編譯器所鏈接!

哦,對了,如果你要實現(xiàn)多個不同的串口打印輸出,不如使用 vsprintf(建議 vsnprintf),好處就是這個函數(shù)的輸出位置不是fputc,而是你給定的緩存空間,這樣你就可以實現(xiàn)自己的printf函數(shù)了。

來源:公眾號【魚鷹談單片機】

作者:魚鷹Osprey

ID   :emOsprey

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉