新聞中心
本文轉載自微信公眾號「編程珠璣」,作者守望先生。轉載本文請聯系編程珠璣(ID:shouwangxiansheng)公眾號。

成都創(chuàng)新互聯公司專注于中大型企業(yè)的成都網站制作、成都網站設計和網站改版、網站營銷服務,追求商業(yè)策劃與數據分析、創(chuàng)意藝術與技術開發(fā)的融合,累計客戶千余家,服務滿意度達97%。幫助廣大客戶順利對接上互聯網浪潮,準確優(yōu)選出符合自己需要的互聯網運用,我們將一直專注成都品牌網站建設和互聯網程序開發(fā),在前進的路上,與客戶一起成長!
在《什么是強符號和弱符號》中簡單介紹了強弱符號,那么強弱符號的性質有什么用呢?
還記得在《什么是強符號和弱符號》中提到的鏈接原則嗎?
- 當有強符號和弱符號時,選擇使用強符號
那么我們正可以利用這個原則做以下事情:
- 定義為弱符號,如果是弱符號,使用默認行為
- 如果鏈接了庫,是強符號,則使用外部定義行為
以此來實現一個類似插件的功能。通俗一點說:
- 當沒有插件時,使用默認行為
- 鏈接了插件時,使用插件的功能
原理和示例
其原理也非常簡單:
- 外部引用弱符號
- 如果符號地址為0,則說明外部沒有鏈接插件庫,未有強符號,走默認流程
- 如果符號地址不為0,則說明鏈接了插件庫,執(zhí)行插件庫的功能。
示例程序如下:
- // 來源:公眾號【編程珠璣】
- // 作者:守望先生
- #include
- __attribute__((weak)) void my_print();
- void test_print()
- {
- // 如果是強符號,說明鏈接了外部插件,使用外部定義
- if(my_print)
- {
- my_print();
- }
- else
- {
- // 弱符號,走默認邏輯
- printf("this is weak print\n");
- }
- }
- int main(void)
- {
- test_print();
- return 0;
- }
上面的test_print函數是弱符號,在沒有其他地方定義的情況下,也是能夠正常編譯運行的:
- $ gcc -o main main.c
- $ ./main
- this is weak print
觀察可執(zhí)行文件:
- $ nm main |grep my_print
- w my_print
通過nm命令我們也可以知道test_print是弱符號,它前面的修飾字符是W,代表weak。
插件庫
前面的示例程序已經能否工作了,如何讓它能否支持插件庫呢?或者說,如何讓它支持外部的插件功能呢?
關于制作庫(靜態(tài)庫或動態(tài)庫制作可以參考《手把手教你制作靜態(tài)庫》)
這里以靜態(tài)庫為例:
- // print_plugin.c
- #include
- void my_print()
- {
- printf("this is plugin print\n");
- }
制作靜態(tài)庫:
- $ gcc -c print_plugin.c
- $ ar -rcs libprint_plugin.a print_plugin.o
鏈接插件庫
現在重新編譯main程序,并使用插件庫:
- $ gcc -o main main.c -L./ -lprint_plugin
- $ gcc -o main main.c -L. -Wl,--whole-archive -lprint_plugin -Wl,--no-whole-archive
- $ nm main |grep my_print
- 000000000000067a T my_print
- $ ./main
- this is plugin print
需要注意的是,這里在鏈接插件庫之前,需要加上:
- -Wl,--whole-archive
該選項會將插件庫中所有符號都鏈接進來,若非如此,在main.c中已經有了my_print符號,將不會鏈接進來,而在此之后,又要將該選項恢復。最終我們可以通過nm命令看到my_print符號已經不再是W了。也就看到了最后:
- this is plugin print
的打印了。
也就實現了我們所謂插件的功能,換句話說,可以對目標程序進行功能的裁剪或者增加。
總結
由于以下幾點原因,我們可以自己做一些支持插件庫的程序:
1.重復強弱符號同存在時,使用強符號
2.弱符號鏈接不存在時,不會報錯
3.未鏈接的外部符號,地址為0,可通過判斷避免訪問非法地址
再結合前面的例子分別解釋一下:
1.這一點在《什么是強符號和弱符號》一文中已經有解釋說明了
2.在開始的程序中,即便沒有鏈接插件庫,程序也可以正常編譯鏈接通過,而不會報錯
3.沒有鏈接插件庫時,由于其函數地址為0,因此,我們程序內判斷,if(xxx),當地址為0時,執(zhí)行默認的行為語句。
標題名稱:騷操作:利用強弱符號制作插件庫
分享路徑:http://www.5511xx.com/article/dpepcgg.html


咨詢
建站咨詢
