大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是MCUXpresso IDE下C++源文件中嵌套定義的復(fù)合數(shù)據(jù)類型命名空間認(rèn)定。
痞子衡之前寫過一篇文章 《MCUXpresso IDE下添加C++源文件進(jìn)SDK工程編譯的方法》,通過這篇文章我們知道嵌入式工程里是能夠支持 C 源文件和 C++ 源文件混合編譯的(因?yàn)橛泻芏?a class="article-link" target="_blank" href="/tag/%E5%BC%80%E6%BA%90/">開源的庫是基于 C++ 語言的,我們需要移植到嵌入式工程里)。
最近有一個 RW612 客戶在使用官方 SDK 時就遇到一個 C/C++ 混合編譯問題,主要涉及復(fù)合數(shù)據(jù)類型(結(jié)構(gòu)體、聯(lián)合體、枚舉)嵌套定義時的命名空間范圍認(rèn)定,今天我們就來聊一聊這個話題:
一、引出編譯問題
客戶使用得是 SDK_2_16_000_RD-RW612-BGA 開發(fā)包里的基礎(chǔ) hello_world 例程模板,當(dāng)客戶嘗試在工程里添加自己創(chuàng)建的 C++ 源文件,并且在該 C++ 源文件中使用 fsl_clock.h 里聲明的如下 clock_frg_clk_config_t 復(fù)合數(shù)據(jù)類型時遇到了編譯錯誤:
typedef?struct?_clock_frg_clk_config
{
????uint8_t?num;
????enum
????{
????????kCLOCK_FrgMainClk?=?0,
????????kCLOCK_FrgPllDiv,
????????kCLOCK_FrgSFro,
????????kCLOCK_FrgFFro,
????}?sfg_clock_src;
????uint8_t?divider;
????uint8_t?mult;
}?clock_frg_clk_config_t;
客戶出現(xiàn)問題的 C++ 源代碼也足夠簡單,只是定義了 clock_frg_clk_config_t 類型的變量 frg_config,并對其中 sfg_clock_src 成員進(jìn)行賦值,結(jié)果編譯報錯 'kCLOCK_FrgPllDiv' was not declared in this scope。
clock_frg_clk_config_t?frg_config;
frg_config.sfg_clock_src?=?kCLOCK_FrgPllDiv;
當(dāng)我們嘗試在 C 源代碼里使用相同的代碼時,編譯是沒問題的,因此可知 clock_frg_clk_config_t 結(jié)構(gòu)體里直接嵌套的 sfg_clock_src 枚舉類型申明在 C 編譯器(arm-none-eabi-gcc)下命名空間是整個文件,而在 C++ 編譯器(arm-none-eabi-c++)下命名空間僅在 clock_frg_clk_config_t 結(jié)構(gòu)體內(nèi)。
二、解決編譯問題
知道了編譯問題和命名空間有關(guān),要解決問題,那就通過 C++ 的作用域解析運(yùn)算符 :: 來解決,修改代碼如下,此時編譯正常。但是這樣是完美的解決方案嗎?很顯然,同樣功能的代碼,在 C/C++ 源文件里寫法不一致,這看起來很別扭。
clock_frg_clk_config_t?frg_config;
frg_config.sfg_clock_src?=?clock_frg_clk_config_t::kCLOCK_FrgPllDiv;
什么是更好的解決方案?答案就是單獨(dú)申明每個復(fù)合數(shù)據(jù)類型原型,讓所有復(fù)合數(shù)據(jù)類型命名空間都一樣,這樣我們統(tǒng)一用 C 語言語法即可。實(shí)際上在恩智浦官方 SDK 里一直是這樣的設(shè)計準(zhǔn)則,客戶遇到的這個情況是個“美麗”的意外。
typedef?enum?_sfg_clock_src
{
????kCLOCK_FrgMainClk?=?0,
????kCLOCK_FrgPllDiv,
????kCLOCK_FrgSFro,
????kCLOCK_FrgFFro,
}?sfg_clock_src_t;
typedef?struct?_clock_frg_clk_config
{
????uint8_t?num;
????sfg_clock_src_t?sfgClockSrc
????uint8_t?divider;
????uint8_t?mult;
}?clock_frg_clk_config_t;
至此,MCUXpresso IDE下C++源文件中嵌套定義的復(fù)合數(shù)據(jù)類型命名空間認(rèn)定痞子衡便介紹完畢了,掌聲在哪里~~~