偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

騷操作:利用強(qiáng)弱符號(hào)制作插件庫(kù)

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

[[384132]] 

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

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

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

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

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

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

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

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

原理和示例

其原理也非常簡(jiǎn)單:

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

示例程序如下:

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

上面的test_print函數(shù)是弱符號(hào),在沒(méi)有其他地方定義的情況下,也是能夠正常編譯運(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 

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

插件庫(kù)

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

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

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

  1. // print_plugin.c 
  2. #include<stdio.h> 
  3. void my_print() 
  4.     printf("this is plugin print\n"); 

制作靜態(tài)庫(kù):

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

鏈接插件庫(kù)

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

  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 

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

  1. -Wl,--whole-archive 

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

  1. this is plugin print 

的打印了。

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

總結(jié)

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

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

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

3.未鏈接的外部符號(hào),地址為0,可通過(guò)判斷避免訪問(wèn)非法地址

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

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

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

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

 

責(zé)任編輯:武曉燕 來(lái)源: 編程珠璣
相關(guān)推薦

2024-11-13 16:19:12

2022-07-27 08:24:44

數(shù)據(jù)庫(kù)RTOSQL

2018-11-30 09:30:46

aiohttp爬蟲(chóng)Python

2020-11-16 07:15:41

Linux權(quán)限管理

2019-05-23 14:59:21

PythonPDF編程語(yǔ)言

2021-04-19 09:15:14

老板公司企業(yè)

2025-03-25 10:49:13

2022-04-25 08:43:47

pandas代碼Python

2022-08-18 15:03:13

并發(fā)編程

2020-11-16 11:50:21

Python代碼命令

2021-06-08 07:04:45

Service Mes微服務(wù)熔斷

2011-07-05 18:04:45

QT Mysql

2020-11-23 11:30:00

IDEA技巧開(kāi)發(fā)

2020-03-16 08:41:00

互聯(lián)網(wǎng)疫情公司

2020-04-03 13:43:23

Python列表推導(dǎo)式字典推導(dǎo)式

2021-11-03 17:04:11

攔截器操作Servlet

2023-07-26 07:41:27

2020-03-11 20:11:06

電腦騷操作AMD

2020-04-27 20:55:42

JavaJava 8編程語(yǔ)言

2021-08-05 18:21:29

Autowired代碼spring
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)