当前位置:首页 > 工业控制 > 电子设计自动化
[导读]作者:杨硕,华清远见嵌入式学院讲师。 1)基本概念 共享库也是.o文件的集合,但是这些文件由编译器按照一种特殊的方式生成(Linux中,共享库文件为"ELF"格式,共享库已经具备了可执行条件)。 共享库的代码是在可执行

作者:杨硕,华清远见嵌入式学院师。

1)基本概念

共享库也是.o文件的集合,但是这些文件由编译器按照一种特殊的方式生成(Linux中,共享库文件为"ELF"格式,共享库已经具备了可执行条件)。

共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

模块中各个成员的地址(变量引用和函数)都是相对地址。使用此共享库的程序在运行时,共享库被动态加载到内存中并和主程序在内存中进行链接。多个可执行程序可以共享库文件的代码段(不共享数据段)。

共享库的成员对象可以被执行(由libdl.so提供支持)。

2)如何建立和使用共享库

1、编写源文件:

源码一:my_strcpy.c:(实现一个strcpy的功能)

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

void my_strcpy(char *des, const char *src)

{

while (*des++ = *src++);

}

源码二:my_strcmp.c(实现一个strcmp的功能)

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int my_strcmp(const char *obj1, const char *obj2)

{

while (*obj1 && *obj2)

{

if (*obj1 - *obj2)

{

return (*obj1 - *obj2);

}

else

{

obj1++;

obj2++;

}

}

return 0;

}

2、生成.o文件

gcc -fPIC -c my_strcpy.c my_strcmp.c

注意:这里与建立静态库有所不同的是要加上参数-fPIC,意思是生成与位置无关的代码,因为共享库链接的时候使用的都是相对地址(偏移量),所以必须指定这项参数。

3、建立共享库

gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1 *.o

-shared代表要建立共享库,-Wl, option代表把选项option传给链接器,这里就是把soname传给链接器,用于指定共享库的版本编号,-o后面是实际的共享库名称。注意,这里共享库的版本号和它的实际名称一样,这样我们就不必再建立符号链接指向实际的名称,可以省去一个符号链接。共享库的版本号是保存在实际的库里的,我们可以执行这个命令:readelf –a libmylib.so.1 | grep libmylib.so.1,就可以看到:

0x0000000e (SONAME) Library soname: [libmylib.so.1]

共享库里的这个版本编号是留给动态加载器(dl)用的,dl会到库里去找这个版本号,完成动态加载的功能。

现在动态加载器可以找到我们创建的共享库了,不过编译器暂时还找不到这个库,我们必须建立一个软链接到实际的库文件,而且这个软链接的文件名必须是以lib开头,以.so结尾的,这是编译器要求的格式。所以我们只需要执行:ln –s libmylib.so.1 libmylib.so就可以了。

也就是说,共享库和静态库不同,静态库只是在编译的时候需要,而共享库在编译和加载的时候都需要,因为它并没有被真正编译进可执行程序,程序里面只是保存了对库函数的符号引用。

4、测试共享库

测试代码main.c和静态库的相同

编译:gcc –o main main.c –L. –lmylib

我们会发现:编译可以通过,但是执行./main终端会打印出:

./main: error while loading shared libraries: libmylib.so.1: cannot open shared object file: No such file or directory

这条信息说明加载共享库的时候出错,加载器找不到libmylib.so.1这个共享库,为什么?这是因为加载器默认的情况下只会到系统指定的路径下去加载共享库,指定路径包括:/usr/lib/和/lib/。要解决这个问题可以有两个办法,一是执行:export LD_LIBRARY_PATH=./把当前路径添加到加载器加载路径的环境变量里面去,当然这样做的话每打开一次终端都要重新执行一遍这个命令;第二种方法是可以在/usr/lib/下或者/lib/下建立一个软链接libmylib.so.1指向真正的库文件libmylib.so.1,这样加载每次都可以找到我们的库文件了,不过我们不推荐这种做法,除非我们制作的共享库很成熟而且经常被用到。

这次再执行./main就可以看到结果:

hello linux.

hello world.

s1 < s2

3)小结

共享库也是.o文件的集合,但它是ELF格式的。

共享库只是在程序开始运行时载入,在编译时,只要简单地指定需要使用的库函数。

动态库是共享库的另一种变化形式。动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不实在程序运行开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行期间释放动态库所占用的内存。共享库和动态库并没有在程序中包含库函数的内容,只是包含了对其的引用,因此代码的规模较小。

“本文由华清远见http://www.embedu.org/index.htm提供”



来源:华清远见0次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭