本文转载自微信公众号「编程珠玑」,作者守望先生。转载本文请联系编程珠玑(ID:shouwangxiansheng)公众号。
成都创新互联公司专注于中大型企业的成都网站制作、成都网站设计和网站改版、网站营销服务,追求商业策划与数据分析、创意艺术与技术开发的融合,累计客户千余家,服务满意度达97%。帮助广大客户顺利对接上互联网浪潮,准确优选出符合自己需要的互联网运用,我们将一直专注成都品牌网站建设和互联网程序开发,在前进的路上,与客户一起成长!
在《什么是强符号和弱符号》中简单介绍了强弱符号,那么强弱符号的性质有什么用呢?
还记得在《什么是强符号和弱符号》中提到的链接原则吗?
那么我们正可以利用这个原则做以下事情:
以此来实现一个类似插件的功能。通俗一点说:
原理和示例
其原理也非常简单:
示例程序如下:
- // 来源:公众号【编程珠玑】
- // 作者:守望先生
- #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
观察可执行文件:
- $ nm main |grep my_print
- w my_print
通过nm命令我们也可以知道test_print是弱符号,它前面的修饰字符是W,代表weak。
插件库
前面的示例程序已经能否工作了,如何让它能否支持插件库呢?或者说,如何让它支持外部的插件功能呢?
关于制作库(静态库或动态库制作可以参考《手把手教你制作静态库》)
这里以静态库为例:
- // print_plugin.c
- #include
- void my_print()
- {
- printf("this is plugin print\n");
- }
制作静态库:
- $ 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时,执行默认的行为语句。
网站名称:骚操作:利用强弱符号制作插件库
分享URL:http://www.mswzjz.cn/qtweb/news15/396065.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能