C程序中让两个不同版本的库共存

原文连接:http://blog.gotocoding.com/archives/875


今天有同学提出,如何在一个C程序中让两个不同版本的库共存。


首先想到的方案是,把其中一个版本的库函数全部重命名,比如把每一个函数名都加一个_v2的后缀。

人工替换到没什么,但是如果函数个数超过10个,就有点不拿人当人使了。


而使有工具去替换就会遇到一些棘手的问题,如何识别哪些是函数,哪些是系统函数(系统函数不需要添加后缀)等。


随后想到的另一个解决方案是c++的方案,为其中一个版本库中的所有文件添加命名空间,然后使用g++将这部分代码编译成. o文件,之后再使用gcc将这些。阿文件与整个程序中的其他代码进行链接。


不过需要注意的是,g++编译后所有导出接口名都会变化得不那么直观。


<人力资源/>


考虑一个C语言的编译链接过程。


首先会将每个C文件编译成。阿文件。


在编译过程中,导出函数并不会被实际分配地址,而是将函数名以F符号的方式存在。阿文件的符号表中。


在本c文件调用的函数如果不存在于本文件,也会生成一个和的符号存在。阿文件的符号表中。


在链接过程中,链接器接收输入的. o文件,为每个。阿文件中的符号分存地址,并生成可执行文件。


有了这几点事实,问题就变得的简单多了。


首先将其中一个版本的库中所有代码编译为. o文件。然后收集所有。阿文件中F的符号。


由于整个库代码有内部依赖关系,收集到的F符号必然是所有。阿文件中和符号的超集。


换句话说,所有的F符号名就是我们要重命名的所有函数名。


这里我们需要借助objdump和objcopy工具.objdump - t用于列的表。阿文件的符号表,objcopy用于重命名符号。


我随手写了一段用于过虑F符号的lua脚本

12345678910111213 <代码类=" lua评论">——重命名。lua代码 <代码类=" lua关键词大胆">本地代码 <代码类=發ua平原”>列表={} <代码类=" lua关键词大胆">本地代码 <代码类=發ua平原”> reg= <代码类=" lua字符串"> " ([^ % s] +) % s + ([^ % s] +) % s + ([^ % s] +)" <代码类=發ua平原”> . . <代码类=發ua空间”>,,,,,,,, <代码类=" lua字符串"> " % s + ([^ % s] +) % s + ([^ % s] +) % s + ([^ % s] +)" <代码类=" lua关键词大胆">为 <代码类=發ua平原”> l <代码类=" lua关键词大胆">在 <代码类=" lua函数大胆"> io <代码类=發ua平原”> .stdin:线条() <代码类=" lua关键词大胆"> 做<代码类=發ua空间”>,,,,,,,, <代码类=" lua关键词大胆">本地代码 <代码类=發ua平原”> a, b, c, d, e, f= <代码类=" lua函数大胆">字符串 <代码类=" lua平原">。匹配(l, reg) <代码类=發ua空间”>,,,,,,,, <代码类=" lua关键词大胆">如果 <代码类=發ua平原”> <代码类=" lua关键词大胆">和 <代码类=發ua平原”> c== <代码类=發ua字符串”>“F” <代码类=" lua关键词大胆">然后 <代码类=發ua空间”>,,,,,,,,,,,,,,,, <代码类=發ua平原”>列表(#列表+ 1)= <代码类=" lua字符串“>”——redefine-sym” <代码类=發ua空间”>,,,,,,,,,,,,,,,, <代码类=發ua平原”>列表(#列表+ 1)= <代码类=" lua函数大胆">字符串 <代码类=" lua平原">。 <代码类=" lua函数大胆">格式 <代码类=發ua平原”>( <代码类=發ua字符串”>“% s=% s_v2” <代码类=發ua平原”>,f, f) <代码类=發ua空间”>,,,,,,,, <代码类=" lua关键词大胆"> 结束<代码类=" lua关键词大胆"> 结束<代码类=" lua函数大胆">打印 <代码类=發ua平原”>( <代码类=發ua字符串”>“#/bin/sh” <代码类=" lua平原">) <代码类=" lua函数大胆">打印 <代码类=發ua平原”>( <代码类=發ua字符串”>“objcopy” <代码类=發ua平原”> . . <代码类=" lua函数大胆">表 <代码类=發ua平原”> .concat(列表). . <代码类=發ua字符串”>“$ 1” <代码类=" lua平原">)

我们可以使用如下命令来收集所有。阿文件的F符号,并产生修改符号所用的脚本1

C程序中让两个不同版本的库共存