linux下制作自己的链接库文件

Linux下有两种库:动态库和静态库(共享库)
二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。
静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在


说了那么多,只是了解一下他们的区别,下面写一个简单的例子


我们需要写3个文件



libhello.h

#ifndef SYMBOL
#define SYMBOL
#include "stdio.h"


void hello();


#endif
///
libhello.c

#include "libhello.h"


void hello(){
printf("hello\n");
}
//
test.c
/
#include "libhello.h"


int main(int argc, char const *argv[])
{
/* code */
hello();
return 0;
}

无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。


静态库:利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。
root@hes-PC:/home/hes/hes/mylib/jingtai# gcc -olibhello.o -c libhello.c  编译成.o文件 1.5k
root@hes-PC:/home/hes/hes/mylib/jingtai# ls
a.out  libhello.c  libhello.h  libhello.o  test.c
root@hes-PC:/home/hes/hes/mylib/jingtai# ar cqs libhello.a libhello.o 编译成.a文件 1.6k
root@hes-PC:/home/hes/hes/mylib/jingtai# ls
a.out  libhello.a  libhello.c  libhello.h  libhello.o  test.c
root@hes-PC:/home/hes/hes/mylib/jingtai# gcc test.c libhello.a 直接使用静态库
root@hes-PC:/home/hes/hes/mylib/jingtai# ./a.out a.out文件8.5k
hello
root@hes-PC:/home/hes/hes/mylib/jingtai# 


动态库:由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便
root@hes-PC:/home/hes/hes/mylib/jingtai# gcc -o -fpic -shared -o libmyhello.so libhello.c  编译成.so.文件 7.9k
root@hes-PC:/home/hes/hes/mylib/jingtai# gcc test.c ./libmyhello.so
root@hes-PC:/home/hes/hes/mylib/jingtai# ./a.out a.out文件8.4k
hello


为了体现升级的优点,下面我写了一个例子
修改libhello.c中的函数内容,改成"你好"


我们重写编译动态库
root@hes-PC:/home/hes/hes/mylib/jingtai# gcc -o -fpic -shared -o libmyhello.so libhello.c  编译成.so.文件 7.9k


然后直接执行
root@hes-PC:/home/hes/hes/mylib/jingtai# ./a.out a.out文件8.4k
你好


主程序运行结果已经发生改变,但是却不用去修改它.只需要编译好动态库,发给用户程序就可以完成升级了.




动态库libd.so与执行程序在同一目录下,如果将libd.so移走再执行程序,程序将不能正常执行。
当需要载入动态库代码时,UNIX会按照某种路径查找动态库
通知UNIX系统动态库的正确位置有如下两种方法.,


1)带编译路径
2)更改环境变量


通过测试可以发现,当静态库和动态库同名时, gcc命令将优先使用动态库.为了确保使用的是静态库, 编译时可以加上 -static  选项,因此多第三方程序为了确保在没有相应动态库时运行正常,喜欢在编译最后应用程序时加入-static


动态库的加载或多或少会占用一定的系统资源,比如内存等。因此当不需要或者一段时间内不需要共享动态库时就要卸载之。函数dlclose关闭参数handle所指向的动态库,卸载其所占的内存等资源,此调用后参数handle无效。
实际上,由于动态库可能同时被多个进程共享,当一个进程指向dlclose时,资源并不马上被卸载,只有当全部进程都宣布关闭动态库后,操作系统才开始回收动态库资源。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux中,生成动态链的步骤如下:首先,使用gcc命令编译生成地址无关代码,可使用选项-fpic来指定编译生成地址无关代码。其次,使用选项-shared来生成动态链文件。例如,可以使用以下命令生成动态链文件libfun.so:gcc -fpic -shared fun.c -o libfun.so。 生成动态链之后,需要将生成的动态链文件复制到系统默认的动态链搜索路径下。通常,系统默认的动态链搜索路径包括/lib、/usr/lib和/usr/local/lib等目录。可以将动态链文件放置在任何一个这些目录下。这样,系统在运行程序时就可以正确地找到动态链。 如果程序在运行时无法找到动态链,可以采取以下几种解决方法之一:将动态链的目录加入程序的搜索路径中。可以将动态链的路径添加到环境变量LD_LIBRARY_PATH中,以实现动态链的搜索。例如,可以使用以下命令将的路径添加到LD_LIBRARY_PATH环境变量中:export LD_LIBRARY_PATH=/path/to/library。这样,程序在运行时就能找到所需的动态链。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Linux制作动态链](https://blog.csdn.net/Oscer2016/article/details/52048957)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值