我已經構建了一個靜態庫(* .a代表gcc,* .lib代表keil)。編譯到庫中的一個源文件包含RADIO_IRQHandler的定義。從這個源文件的摘錄,被稱爲「ral_irq_handlers.c」,低於:在靜態庫中定義的IRQ符號不會覆蓋來自ARM/GCC啓動的弱IRQ定義
...
void ral_symbol_import(void) //dummy function
{
return;
}
...
void RADIO_IRQHandler(void)
{
...
}
...
該IRQ符號定義應該重寫它在啓動文件中聲明的弱定義。啓動文件不會編譯到任何靜態庫中,只是項目中的常規文件。
arm_startup_xxx.s文件(keil的工具鏈)的摘錄低於:
Default_Handler PROC
...
EXPORT RADIO_IRQHandler [WEAK]
...
...
RADIO_IRQHandler
...
B .
ENDP
ALIGN
類似gcc_startup_xxx.s文件(gcc工具)的摘錄低於:
.globl Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
.macro IRQ handler
.weak \handler
.set \handler, Default_Handler
.endm
...
IRQ RADIO_IRQHandler
...
.end
然後我觀察到一個奇怪的行爲。當我在其中一個項目源文件中使用來自「ral_irq_handlers.c」源文件(編譯爲庫)的任何API函數時,鏈接都會正確完成。例如:
...
int main(void)
{
ral_symbol_import();
...
}
...
但是,如果我不使用「ral_irq_handlers.c」源文件的任何API函數,鏈接器不能找到我的庫中定義的RADIO_IRQHandler符號。我可以以某種方式做到這一點沒有這個醜陋的黑客(調用虛擬函數強制正確的鏈接)?
我想只修改庫代碼而不接觸啓動文件。
連接標誌工作得很好,但它非常有創意。你可以以某種方式聲明無效的RADIO_IRQHandler(void)函數在庫中更加可見(某些特殊語句)嗎?或者可能以這種特殊符號正確鏈接的方式構建庫? – aldarel
@aldarel - 對不起,我不知道可以從圖書館「內部」工作的其他選項......我擁有的所有解決方案都針對使用圖書館的項目。您還可以通過鏈接器腳本(或鏈接器命令行)強制鏈接某個符號,但這是同樣的事情。我曾經有類似的問題,這些都是我從這裏得到的 - https://sourceware.org/ml/binutils/2015-09/msg00272.html –