日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
騷操作:利用強(qiáng)弱符號制作插件庫

本文轉(zhuǎn)載自微信公眾號「編程珠璣」,作者守望先生。轉(zhuǎn)載本文請聯(lián)系編程珠璣(ID:shouwangxiansheng)公眾號。

成都創(chuàng)新互聯(lián)公司專注于中大型企業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計(jì)客戶千余家,服務(wù)滿意度達(dá)97%。幫助廣大客戶順利對接上互聯(lián)網(wǎng)浪潮,準(zhǔn)確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運(yùn)用,我們將一直專注成都品牌網(wǎng)站建設(shè)和互聯(lián)網(wǎng)程序開發(fā),在前進(jìn)的路上,與客戶一起成長!

在《什么是強(qiáng)符號和弱符號》中簡單介紹了強(qiáng)弱符號,那么強(qiáng)弱符號的性質(zhì)有什么用呢?

還記得在《什么是強(qiáng)符號和弱符號》中提到的鏈接原則嗎?

  • 當(dāng)有強(qiáng)符號和弱符號時(shí),選擇使用強(qiáng)符號

那么我們正可以利用這個(gè)原則做以下事情:

  • 定義為弱符號,如果是弱符號,使用默認(rèn)行為
  • 如果鏈接了庫,是強(qiáng)符號,則使用外部定義行為

以此來實(shí)現(xiàn)一個(gè)類似插件的功能。通俗一點(diǎn)說:

  • 當(dāng)沒有插件時(shí),使用默認(rèn)行為
  • 鏈接了插件時(shí),使用插件的功能

原理和示例

其原理也非常簡單:

  • 外部引用弱符號
  • 如果符號地址為0,則說明外部沒有鏈接插件庫,未有強(qiáng)符號,走默認(rèn)流程
  • 如果符號地址不為0,則說明鏈接了插件庫,執(zhí)行插件庫的功能。

示例程序如下:

 
 
 
  1. // 來源:公眾號【編程珠璣】
  2. // 作者:守望先生
  3. #include
  4. __attribute__((weak)) void my_print();
  5.  void test_print()
  6. {
  7.     // 如果是強(qiáng)符號,說明鏈接了外部插件,使用外部定義
  8.     if(my_print)
  9.     {
  10.         my_print();
  11.     }
  12.     else
  13.     {
  14.         // 弱符號,走默認(rèn)邏輯
  15.         printf("this is weak print\n");
  16.     }
  17. }
  18. int main(void)
  19. {
  20.     test_print();
  21.     return 0;
  22. }

上面的test_print函數(shù)是弱符號,在沒有其他地方定義的情況下,也是能夠正常編譯運(yùn)行的:

 
 
 
  1. $ gcc -o main main.c
  2. $ ./main
  3. this is weak print

觀察可執(zhí)行文件:

 
 
 
  1. $ nm main |grep my_print
  2.            w my_print

通過nm命令我們也可以知道test_print是弱符號,它前面的修飾字符是W,代表weak。

插件庫

前面的示例程序已經(jīng)能否工作了,如何讓它能否支持插件庫呢?或者說,如何讓它支持外部的插件功能呢?

關(guān)于制作庫(靜態(tài)庫或動態(tài)庫制作可以參考《手把手教你制作靜態(tài)庫》)

這里以靜態(tài)庫為例:

 
 
 
  1. // print_plugin.c
  2. #include
  3. void my_print()
  4. {
  5.     printf("this is plugin print\n");
  6. }

制作靜態(tài)庫:

 
 
 
  1. $ gcc -c print_plugin.c
  2. $ ar -rcs libprint_plugin.a print_plugin.o

鏈接插件庫

現(xiàn)在重新編譯main程序,并使用插件庫:

 
 
 
  1. $ gcc -o main main.c -L./ -lprint_plugin
  2. $ gcc  -o main  main.c  -L. -Wl,--whole-archive -lprint_plugin -Wl,--no-whole-archive
  3. $ nm main |grep my_print
  4. 000000000000067a T my_print
  5. $ ./main
  6. this is plugin print

需要注意的是,這里在鏈接插件庫之前,需要加上:

 
 
 
  1. -Wl,--whole-archive

該選項(xiàng)會將插件庫中所有符號都鏈接進(jìn)來,若非如此,在main.c中已經(jīng)有了my_print符號,將不會鏈接進(jìn)來,而在此之后,又要將該選項(xiàng)恢復(fù)。最終我們可以通過nm命令看到my_print符號已經(jīng)不再是W了。也就看到了最后:

 
 
 
  1. this is plugin print

的打印了。

也就實(shí)現(xiàn)了我們所謂插件的功能,換句話說,可以對目標(biāo)程序進(jìn)行功能的裁剪或者增加。

總結(jié)

由于以下幾點(diǎn)原因,我們可以自己做一些支持插件庫的程序:

1.重復(fù)強(qiáng)弱符號同存在時(shí),使用強(qiáng)符號

2.弱符號鏈接不存在時(shí),不會報(bào)錯(cuò)

3.未鏈接的外部符號,地址為0,可通過判斷避免訪問非法地址

再結(jié)合前面的例子分別解釋一下:

1.這一點(diǎn)在《什么是強(qiáng)符號和弱符號》一文中已經(jīng)有解釋說明了

2.在開始的程序中,即便沒有鏈接插件庫,程序也可以正常編譯鏈接通過,而不會報(bào)錯(cuò)

3.沒有鏈接插件庫時(shí),由于其函數(shù)地址為0,因此,我們程序內(nèi)判斷,if(xxx),當(dāng)?shù)刂窞?時(shí),執(zhí)行默認(rèn)的行為語句。


當(dāng)前名稱:騷操作:利用強(qiáng)弱符號制作插件庫
網(wǎng)站網(wǎng)址:http://www.dlmjj.cn/article/dpepcgg.html