[Linux]链接,静态库和动态库

合集下载

linux动态库静态库函数覆盖

linux动态库静态库函数覆盖

linux动态库静态库函数覆盖本⽂讨论了linux动态库静态库中函数的覆盖问题。

测试⽬的:同名函数,分别打成动态库libdync_lib.so与静态库libstatic_lib.a,并把libstatic_lib.a打到另⼀个动态库libapi.so中,在可执⾏程序中分别连接libdync_lib.so与libapi.so,此时到底调⽤的是哪个库中的函数?测试结论:不同库中的同名函数会被覆盖,后链接的库中的同名函数会被先前库覆盖。

测试⽅法:static_lib.h1void print();static_lib.cpp1 #include <cstdio.h>2 #include "static_lib.h"34void print()5 {6 printf("i am static print\n");7 }dync_lib.h1void print();dync_lib.cpp#include <cstdio.h>#include "dync_lib.h"void print(){printf("i am dync print\n");}api.hvoid func();api.cpp1 #include "static_lib.h"23void func()4 {5 print();6 }main.cpp#include <api.h>int main(){func();print();return0;}制作libdync_lib.so动态库g++ dync_lib.cpp -shared -fPIC -o libdync_lib.so制作libstatic_lib.a静态库g++ -c static_lib.cpp -share -fPIC -o static_lib.oar crv libstatic_lib.a static_lib.o制作libapi.so动态库,其依赖静态库libstatic_lib.ag++ api.cpp -shared -fPIC -o libapi.so -lstatic_lib有三种⽅式⽣成可执⾏程序1、g++ main.cpp -lapi -o main2、g++ main.cpp -lapi -ldync_lib -o main3、g++ main.cpp -ldync_lib -lapi -o main每种⽅式都能执⾏成功,但输出不⼀样,1、2执⾏时,输出⼀致:i am static print3执⾏时,输出;i am dync print下⾯分析原因:1、第⼀种⽅式中,main.cpp中只包含了 api.h,⽽api.h中并没有定义print函数,那么main中怎么找到了该函数并且调⽤成功了呢?因为,⽣成libapi.so时连接了libstatic_lib.a,⽽其中包含print,也就是说,静态库中的函数符号都会被打到动态库中,所以main能找到print 函数的实现,来⾃libstatic_lib.a。

静态链接库和动态链接库的区别及优缺点

静态链接库和动态链接库的区别及优缺点

静态链接库和动态链接库的区别及优缺点动态链接库和静态链接库的区别本⽂参考了以下博客:1. /gamecreating/article/details/55041522. /left_la/article/details/120985453. /augusdi/article/details/6460415静态连接库就是把(lib)⽂件中⽤到的函数代码直接链接进⽬标程序,程序运⾏的时候不再需要其它的库⽂件;动态链接就是把调⽤的函数所在⽂件模块(DLL)和调⽤函数在⽂件中的位置等信息链接进⽬标程序,程序运⾏的时候再从DLL中寻找相应函数代码,因此需要相应DLL⽂件的⽀持。

静态链接库与动态链接库都是共享代码的⽅式,如果采⽤静态链接库,则⽆论你愿不愿意,lib 中的指令都全部被直接包含在最终⽣成的 EXE ⽂件中了。

但是若使⽤ DLL,该 DLL 不必被包含在最终 EXE ⽂件中,EXE ⽂件执⾏时可以“动态”地引⽤和卸载这个与 EXE 独⽴的 DLL ⽂件。

静态链接库和动态链接库的另外⼀个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,⽽在动态链接库中还可以再包含其他的动态或静态链接库。

动态库就是在需要调⽤其中的函数时,根据函数映射表找到该函数然后调⼊堆栈执⾏。

如果在当前⼯程中有多处对dll⽂件中同⼀个函数的调⽤,那么执⾏时,这个函数只会留下⼀份拷贝。

但是如果有多处对lib⽂件中同⼀个函数的调⽤,那么执⾏时,该函数将在当前程序的执⾏空间⾥留下多份拷贝,⽽且是⼀处调⽤就产⽣⼀份拷贝。

静态链接库与静态链接库调⽤规则总体⽐较如下:1、静态链接库(⽐较简单):⾸先,静态链接库的使⽤需要库的开发者提供⽣成库的.h头⽂件和.lib⽂件。

⽣成库的.h头⽂件中的声明格式如下:extern "C" 函数返回类型函数名(参数表);在调⽤程序的.cpp源代码⽂件中如下:#include "../lib.h"#pragma comment(lib,"..//debug//libTest.lib") //指定与静态库⼀起链接其次因为静态链接库是将全部指令都包含⼊调⽤程序⽣成的EXE⽂件中。

静态库和动态库编译

静态库和动态库编译

静态库和动态库编译静态库和动态库是编程中常用的两种库文件形式,本文将介绍它们的编译过程和使用方法。

1. 静态库编译静态库是一种在编译时被链接到程序中的库文件,它包含了程序所依赖的所有函数和数据结构,因此程序在运行时不需要再加载库文件。

静态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件(.o 或 .obj)。

(2)将多个目标文件打包成一个静态库文件,通常使用 ar 工具完成此操作。

例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.a 的静态库文件:$ ar rcs libfoo.a foo1.o foo2.o ...其中,rcs 参数分别表示创建、向库文件中添加目标文件和生成索引表。

(3)在编译器中使用静态库,需要将其链接到目标程序中。

在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.a 的静态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 参数指定库文件搜索路径,. 表示当前目录;-l 参数指定链接库文件,实际上是将其前缀 lib 和后缀 .a 去掉,即 foo。

2. 动态库编译动态库是一种在程序运行时动态加载的库文件,它只包含程序所需要的部分函数和数据结构,因此可以减小程序的尺寸和加载时间。

动态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件。

(2)将多个目标文件打包成一个共享库文件,通常使用 ld 或链接器完成此操作。

例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.so 的动态库文件:$ gcc -shared -o libfoo.so foo1.o foo2.o ...其中,-shared 参数表示生成共享库文件。

(3)在编译器中使用动态库,需要将其链接到目标程序中。

在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.so 的动态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 和 -l 参数的含义同静态库。

linux.o,.a,.so文件解析

linux.o,.a,.so文件解析

linux .o,.a,.so文件解析来源: ChinaUnix博客日期:2007.04.18 08:18(共有0条评论) 我要评论/yanyulou类型是不依赖于其后缀名的,但一般来讲:,相当于windows中的.obj文件是shared object,用于动态连接的,和dll差不多好多个.o合在一起,用于静态连接自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息。

可以用如下命令查看*.la文件的格式 $file *.la CII English text来查看其内容。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@和.o库文件:host perl_c2]$ pwdperl_c2host perl_c2]$ cat mylib.c"success call from perl to c library\n");host perl_c2]$ cat mylib.hello();host perl_c2]$ gcc -c mylib.chost perl_c2]$ dirb.h mylib.ohost perl_c2]$ ar -r mylib.a mylib.omylib.ahost perl_c2]$ dirb.c mylib.h mylib.o@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1111111111111111111111111111111111111111111111111111111111111111111111111111111 so的编译与使用- -linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。

译例子来介绍如何生成一个动态库。

这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,个动态库:libtest.so。

linux中编译静态库(.a)和动态库(.so)的基本方法_onlyyou

linux中编译静态库(.a)和动态库(.so)的基本方法_onlyyou

linux中编译静态库(.a)和动态库(.so)的基本方法_onlyyou展开全文静态库在linux环境中, 使用ar命令创建静态库文件.如下是命令的选项:d -----从指定的静态库文件中删除文件m -----把文件移动到指定的静态库文件中p -----把静态库文件中指定的文件输出到标准输出q -----快速地把文件追加到静态库文件中r -----把文件插入到静态库文件中t -----显示静态库文件中文件的列表x -----从静态库文件中提取文件还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:a -----把新的目标文件(*.o)添加到静态库文件中现有文件之后b -----***************************************之前v -----使用详细模式ar 命令的命令行格式如下:ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件.比如创建一个静态库文件的命令如下:ar r libapue.a error.o errorlog.o lockreg.o这样就了libapue.a静态库文件, 可以用t 选项显示包含在库中的文件创建库文件之后,可以创建这个静态库文件的索引来帮助提高和库连接的其他程序的编译速度.使用ranlib程序创建库的索引,索引存放在库文件内部.ranlib libapue.a用nm程序显示存档文件的索引,它可以显示目标文件的符号nm libapue.a | more如果是显示目标文件的符号:nm error.o | more如何使用呢?如下所示:gcc -o test test.c libapue.a这样就可以在test.c中调用在libapue.a中的函数了.动态库1.创建共享库gcc -shared -o libapue.so error.o errorlog.o这样就创建了共享库!2.编译共享库假设共享库位于当前目录(即跟程序文件相同的目录中)gcc -o test -L. -lapue test.c这样就编译出了不包含函数代码可执行文件了,但是但你运行时会发现linux动态加载器打不到libapue.so文件.可以用ldd 命令查看可执行文件依赖什么共享库:ldd test如何才能让动态加载器发现库文件呢?有两种方法可以解决:LD_LIBRARY_PATH 环境变量/etc/ld.so.conf文件1.环境变量export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."2.修改/etc/ld.so.conf文件.位于/etc/ld.so.conf一般应用程序的库文件不与系统库文件放在同一个目录下,一般把应用程序的共享库文件放在/usr/local/lib下,新建一个属于自己的目录apue,然后把刚才libapue.so复制过去就行了同时在/etc/ld.so.conf中新增一行:/usr/local/lib/apue以后在编译程序时加上编译选项:-L/usr/local/lib/apue -lapue这样就可以使用这个libapue.so共享库了!!全文结束!!写此文章参考了:<<Professional Assembly Language>>. 这是一本好书!如果是学习AT&T汇编语法,建议阅读此书!!。

linux动态库和静态库调用方法

linux动态库和静态库调用方法

linux动态库和静态库调用方法
在Linux操作系统中,动态库和静态库的调用方法如下:
1. 动态库(Shared Library):动态库在程序运行时被载入内存,可以被多个程序同时使用,节省内存空间。

在Linux中,动态库一般存放在/usr/lib或/lib目录下。

调用方法:在程序中使用extern "C"来声明函数接口,然后通过dlopen(), dlsym()等函数来动态调用动态库中的函数。

2. 静态库(Static Library):静态库在程序编译时被包含进可执行程序中,每个程序都有一份自己的库副本。

静态库一般存放在/usr/lib或/lib目录下。

调用方法:在程序中直接使用静态库中的函数,不需要额外的调用方法。

只需要在编译时使用"-l"选项指定要链接的库名,例如"gcc -o test test.c -lmylib"。

需要注意的是,对于动态库和静态库的使用,一般建议优先使用动态库,因为这样可以节省内存空间,并且可以在不停止程序运行的情况下更新库文件。

第1页/ 共1页。

目标文件符号《深入理解计算机系统》笔记(三)链接知识【附图】

目标文件符号《深入理解计算机系统》笔记(三)链接知识【附图】

⽬标⽂件符号《深⼊理解计算机系统》笔记(三)链接知识【附图】每⽇⼀贴,今天的内容关键字为⽬标⽂件符号该书中对链接的解释也不敷具体。

在章节最后,作者也否认:在计算机系统⽂献中并没有很好的记录链接。

因为链接是处在编译器、计算机体系结构和操作系统的交叉点上,他要求懂得代码⽣成、机器语⾔编程、程序实例化和虚拟存储器。

它恰好不落在某个平⽇的计算机系统领域中。

该章节报告Linux的X86系统,使⽤标准的ELF⽬标⽂件,⽆论是什么样的操作系统,细节可能不尽相同,但是观点是相同的。

读完这⼀章节后,对“符号”的观点很是模糊。

7.1编译驱动程序这⾥再说⼀下编译系统。

⼤多数编译系统提供编译驱动程序,它代表⽤户在需要的时候调⽤语⾔预处置、编译器、汇编器、和链接器。

我⾃⼰画了⼀个结构图。

7.2静态链接7.3⽬标⽂件⽬标⽂件有三种:可重定位⽬标⽂件、可执⾏⽬标⽂件和同享⽬标⽂件(即动态链接库),个个系统上对⽬标⽂件的叫法不⼀致,Unix叫a.out,Windows NT叫PE(Portable Executable)。

现代Unix使⽤ELF格式(EXecutable and Linkable Format 即可执⾏和可链接格式)。

下⾯具体介绍“可重定位⽬标⽂件”,下图最左边的⼀个图。

上图说明了,⼀个⽬标⽂件⽣成可执⾏⽂件,然后加载到内存后的映射等,三个步骤。

ELF头描述了⽣成该⽂件的系统的字的巨细和字节序。

ELF和节头部表之间每⼀个部份都称为⼀个节(section).text:已编译程序的机器代码.rodada:只读数据,⽐如printf语句中的格式串。

.data:已初始化的全局C变量。

局部变量在运⾏时保存在栈中。

即不再data节也不在bss节.bss:未初始化的全局C变量。

不占据实际的空间,仅仅是⼀个占位符。

所以未初始化变量不需要占据任何实际的磁盘空间。

C++弱化BSS段。

多是没有,也可能有。

.symtab:⼀个符号表,它存放“在程序中定义和引⽤的函数和全局变量的信息”。

嵌入式系统程序设计(6章)赖晓晨

嵌入式系统程序设计(6章)赖晓晨

4. 共享库错误函数
函数原型: const char *dlerror(void); 功能描述:当动态链接库操作函数 (dlopen、dlsym、dlclose)执 行失败时,dlerror可以返回出错信息, 返回值为NULL时表示操作函数执行成 功。
【例6-2】
/* ch6_2 sub.h */ #ifndef SUB_H #define SUB_H int square(int); #endif /* ch6_2 sub.c */ #include <stdio.h> int square(int a) { printf("the square of the number is:"); return a*a; }
打开共享库(续)
功能描述:参数中的libname一般是库的绝对路径, 这样dlopen会直接装载该文件;如果只是指定了库名 称,在dlopen会按照下面的机制去搜寻:
根据环境变量LD_LIBRARY_PATH查找; 根据/etc/ld.so.cache查找; 依次在/lib和/usr/lib目录查找。
库分类
静态库,是在执行程序运行前就已经加入到执 行码中,在物理上成为执行程序的一部分。
共享库,是在执行程序启动时加载到执行程序 中,可以被多个执行程序共享使用。 动态链接库,其实并不是一种真正的库类型, 应该是一种库的使用技术,应用程序可以在运 行过程中随时加载和使用库。
库命名约定
所有库都以lib开头,表示一个库文件;
}
handle=dlopen("/lib/libmydll.so", RTLD_LAZY); if(!handle) { printf("%s\n",dlerror()); 如未找到函数,显 } 示error中的错误 fp=dlsym(handle, "square"); 信息 if((error=dlerror())!=NULL) { printf("%s\n",error); dlclose(handle); exit(1); } printf("now call the function square.\n"); result = (*fp)(n); printf(" %d\n",result); dlclose(handle); return 0;

静态链接库与动态链接库的异同点

静态链接库与动态链接库的异同点

先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。

在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。

静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都被直接包含在最终生成的EXE文件中了。

但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。

静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

目标库(Object Libraries)目标库又叫静态链接库,是扩展名为.LIB的文件,包括了用户程序要用到的各种函数。

它在用户程序进行链接时,“静态链接”到可执行程序文件当中。

例如,在VC++中最常使用到的C运行时目标库文件就是LIBC.LIB。

在链接应用程序时常使用所谓“静态链接”的方法,即将各个目标文件(.obj)、运行时函数库(.lib)以及已编译的资源文件(.res)链接到一起,形成一个可执行文件(.exe)。

使用静态链接时,可执行文件需要使用的各种函数和资源都已包含到文件中。

这样做的缺点是对于多个程序都使用的相同函数和资源要重复链接到exe 文件中,使程序变大、占用内存增加。

动态链接库(Dynamic-Link Libraries)“动态链接”是将一些公用的函数或资源组织成动态链接库文件(.dll),当某个需要使用dll中的函数或资源的程序启动时(准确的说是初始化时),系统将该dll映射到调用进程的虚拟地址空间、增加该dll的引用计数值,然后当实际使用到该dll时操作系统就将该dll载入内存;如果使用该dll的所有程序都已结束,则系统将该库从内存中移除。

使用同一dll的各个进程在运行时共享dll 的代码,但是对于dll中的数据则各有一份拷贝(当然也有在dll中共享数据的方法)。

linux给运行程序指定动态库路径

linux给运行程序指定动态库路径

linux给运⾏程序指定动态库路径1. 连接和运⾏时库⽂件搜索路径到设置库⽂件在连接(静态库和共享库)和运⾏(仅限于使⽤共享库的程序)时被使⽤,其搜索路径是在系统中进⾏设置的。

⼀般 Linux 系统把 /lib 和 /usr/lib 两个⽬录作为默认的库搜索路径【deepin可以在⾥⾯搜索出qt,因为deepin默认安装了qt程序运⾏依赖库】,所以使⽤这两个⽬录中的库时不需要进⾏设置搜索路径即可直接使⽤。

对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。

设置库⽂件的搜索路径有下列两种⽅式,可任选其⼀使⽤:(1). 在 /etc/ld.so.conf ⽂件中添加库的搜索路径。

(或者在/etc/ld.so.conf.d 下新建⼀个.conf⽂件,将搜索路径⼀⾏⼀个加⼊-junziyang)将⾃⼰可能存放库⽂件的路径都加⼊到/etc /ld.so.conf中是明智的选择添加⽅法也极其简单,将库⽂件的绝对路径直接写进去就OK了,⼀⾏⼀个。

例如:/usr/X11R6/lib/usr/local/lib/opt/lib需要注意的是:这种搜索路径的设置⽅式对于程序连接时的库(包括共享库和静态库)的定位已经⾜够了,但是对于使⽤了共享库的程序的执⾏还是不够的。

这是因为为了加快程序执⾏时对共享库的定位速度,避免使⽤搜索路径查找共享库的低效率,所以是直接读取库列表⽂件 /etc/ld.so.cache 从中进⾏搜索的。

/etc/ld.so.cache 是⼀个⾮⽂本的数据⽂件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库⽂件集中在⼀起⽽⽣成的(ldconfig 命令要以 root 权限执⾏)。

因此,为了保证程序执⾏时对库的定位,在 /etc/ld.so.conf 中进⾏了库搜索路径的设置之后,还必须要运⾏/sbin/ldconfig 命令更新 /etc/ld.so.cache ⽂件之后才可以。

动态库依赖动态库,静态库依赖静态库,顺序

动态库依赖动态库,静态库依赖静态库,顺序

动态库依赖动态库,静态库依赖静态库,顺序静态库依赖静态库,有顺序的问题,否则undefined reference⾄于动态链接,链接器会对依赖进⾏整理,避免这个问题。

动态库就不存在依赖顺序的问题。

如果库是相互独⽴的,则顺序不重要。

如果不是相互独⽴,那么必须对它们进⾏排序对于⽇常命令⾏编译命令,⼀般从左到右分别是可执⾏⽂件 ——> ⾼级库 ——> 底层库,避免循环依赖;越是底层的库,越是往后⾯写,可以参考下述命令通式:g++ ... obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib) -o $@静态库有顺序问题,并且要把⾃⼰的库所依赖的所有的第三⽅库都要显⽰的指定出来。

动态库⽆顺序问题,并且只需要显⽰的连接⾃⼰的动态库,⾃⼰的动态库依赖的第三⽅的动态库⽆需显⽰指定,⾃⼰会从rpath中⾃动连接第三⽅的动态库。

但必须把第三⽅库依赖的所有的库,包括路径都拷贝出来。

例如使⽤libevent.so, 此时需要把下⾯这⼀堆⽂件都拷贝出来:lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent-2.1.so.7 -> libevent-2.1.so.7.0.1-rwxr-xr-x. 1 root root 386024 Mar 25 15:18 deps/so/libevent-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core-2.1.so.7 -> libevent_core-2.1.so.7.0.1-rwxr-xr-x. 1 root root 241936 Mar 25 15:17 deps/so/libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 26 Mar 25 15:17 deps/so/libevent_core.so -> libevent_core-2.1.so.7.0.1lrwxrwxrwx. 1 root root 21 Mar 25 15:18 deps/so/libevent.so -> libevent-2.1.so.7.0.1把第三⽅静态库链接到⾃⼰的.so动态库,编译第三⽅静态库的时候需要加 -fPIC这个参数。

linux动态库调用方法

linux动态库调用方法

linux动态库调用方法Linux动态库调用方法动态库是一种程序库,它在程序运行时才会被加载和链接,相对于静态库来说,动态库更加灵活和高效。

在Linux系统中,动态库的调用方法有多种,本文将介绍其中的一些常用方法。

1. 静态调用静态调用是指在编译链接阶段将动态库的代码完全复制到可执行文件中,使得可执行文件不再依赖于动态库。

在Linux系统中,静态调用需要使用静态库文件(以.a为后缀),可以通过在编译命令中添加-l参数来指定静态库文件的路径。

例如:```gcc main.c -L/path/to/lib -lmylib -o main```其中,/path/to/lib是动态库所在的路径,mylib是动态库的名称,main是生成的可执行文件名。

2. 动态调用动态调用是指在程序运行时动态加载和链接动态库。

在Linux系统中,动态调用需要使用动态库文件(以.so为后缀),可以通过以下几种方法进行动态调用。

(1)dlopen/dlsymdlopen和dlsym是Linux系统提供的动态库加载和符号查找函数。

dlopen函数用于加载动态库,dlsym函数用于查找动态库中的符号。

可以通过以下代码进行调用:```c#include <dlfcn.h>void* handle = dlopen("/path/to/libmylib.so", RTLD_LAZY);if (handle == NULL) {printf("Failed to load library: %s\n", dlerror());return -1;}void (*function)() = dlsym(handle, "my_function");if (function == NULL) {printf("Failed to find symbol: %s\n", dlerror());dlclose(handle);return -1;}function();dlclose(handle);```其中,/path/to/libmylib.so是动态库所在的路径,my_function 是动态库中的函数名。

【linux】程序找不到动态库.so的解决办法查看.so动态库信息.so动态库加载顺序

【linux】程序找不到动态库.so的解决办法查看.so动态库信息.so动态库加载顺序

【linux】程序找不到动态库.so的解决办法查看.so动态库信息.so动态库加载顺序⽬录找不到.so解决⽅法Linux 动态库的默认搜索路径是 /lib 和 /usr/lib,除了默认的搜索路径外,还可以通过以下⼏种⽅法来指定。

⽅法⼀:添加环境变量添加环境变量三种⽅式1. 添加当前⽤户当前终端的环境变量(临时)export LD_LIBRARY_PATH=/home/czd/... #.so file path2. 添加当前⽤户的环境变量修改~/.bashrc⽂件,在其末尾,添加环境变量vim ~/.bashrcexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/czd/... #.so file path使其⽣效,source ~/.bashrc如不能⽣效,请重启3. 添加所有⽤户的环境变量修改profile⽂件,在其末尾添加环境变量vim /etc/profileexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/czd/... #.so file path使其⽣效source /etc/profile如不能⽣效,请重启⽅法⼆:复制so⽂件到lib路径linux系统的so库⼀般存储与“/usr/lib/”路径中,可将动态库复制到该路径中。

sudo cp liblibtest.so /usr/lib/即时⽣效⽅法三:(推荐)添加ldconfig寻找路径步骤1. 编辑链接配置⽂件vim /etc/ld.so.conf,确认内容是否为如下,不是则修改为如下:include /etc/ld.so.conf.d/*.conf步骤2. 进⼊/etc/ld.so.conf.d⽬录内,创建*.conf⽂件,⽂件名随意,扩展名必须为.confcd /etc/ld.so.conf/vim libmy.conf步骤4. 在⽂件内部,添加so的路径,保存并退出/home/czd/eclipse-workspacee/calllib/Debug步骤5. 执⾏命令时期⽣效sudo ldconfig程序在运⾏时寻找so库就会到添加的⽬录中寻找。

linux下用gcc生成静态库和动态库

linux下用gcc生成静态库和动态库

linux下用gcc生成静态库和动态库我们通常把一些公用函数制作成函数库,供其它程序使用。

函数库分为静态库和动态库两种。

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。

在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o 文件。

第1步:编辑得到举例的程序--hello.h、hello.c和main.c;hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。

hello.h(见程序1)为该函数库的头文件。

main.c(见程序3)为测试库文件的主程序,在主程序中调用了公用函数hello。

#ifndef HELLO_H#define HELLO_Hvoid hello(const char *name);#endif //HELLO_H程序1: hello.h#include <stdio.h>void hello(const char *name){printf("Hello %s!\n", name);}程序2: hello.c#include "hello.h"int main(){hello("everyone");return 0;}程序3: main.c第2步:将hello.c编译成.o文件;无论静态库,还是动态库,都是由.o文件创建的。

因此,我们必须将源程序hello.c通过gcc先编译成.o文件。

在系统提示符下键入以下命令得到hello.o文件。

# gcc -c hello.c#我们运行ls命令看看是否生存了hello.o文件。

头文件和库文件-静态库和动态库

头文件和库文件-静态库和动态库

头⽂件和库⽂件-静态库和动态库⼀、头⽂件和库⽂件头⽂件提供声明,库⽂件提供定义/实现。

C代码的编译过程: 预处理(需要头⽂件) -> 编译 -> 汇编 -> 链接(需要库⽂件); 执⾏时可能还有动态链接过程。

编译的时候,只要有头⽂件中的声明就⾜够了。

在链接的时候,把已经编译好的.obj和现有的.lib⽂件进⾏链接,这时就可以最终⽣成可执⾏⽂件了。

其实头⽂件与其实现⽂件或相应lib⽂件都没有直接的联系。

头⽂件是告诉编译器函数是如何去调⽤如何返回的,所有实现都是分别编译,最后在链接阶段链在⼀起。

头⽂件包含声明, 库⽂件包含实现或者与DLL库的连接所以,如果在代码⾥要⽤到这些函数那么就要包含头⽂件,编译的时候才能知道这些函数的原形;在进⾏代码连接的时候就需要库⽂件了,这时连接器就把函数的实现代码(静态库)连接到你的程序或者将你的函数调⽤连接到相应的DLL的对应函数(动态库)lib是静态库, 编译的时候代码直接插⼊到你的程序 ,DLL是动态库,编译的时候,只是产⽣⼀些调⽤DLL内代码的导⼊表,真正运⾏的时候是调⽤的DLL内的代码。

总结起来就是,库⽂件通过头⽂件向外导出接⼝。

⽤户通过头⽂件找到库⽂件中函数实现的代码从⽽把这段代码链接到⽤户程序中去。

.a代表传统的静态函数库(也称作归档⽂件:archive).so代表共享函数库⼆、创建静态库⽂件:1.创建源⽂件willku1.c和willku2.c2.编译源⽂件⽣成.o⽂件(将要包含在库⽂件中的⽬标⽂件)gcc -c willku1.c willku2.c =>willku1.o willku2.o3.创建头⽂件ishead.h内容:void willku1(char *);void willku2(int);4.创建应⽤程序app.c(将调⽤willku2.c⽂件)#include "ishead.h"5.编译、测试应⽤程序app.cgcc -c app.cgcc -o app app.o willku2.o./app6.创建并使⽤库⽂件(.a),使⽤ar创建归档⽂件并将⽬标⽂件加进去。

Linux命令高级技巧使用gcc命令进行CC编译和链接

Linux命令高级技巧使用gcc命令进行CC编译和链接

Linux命令高级技巧使用gcc命令进行CC编译和链接Linux命令高级技巧:使用gcc命令进行C/C++编译和链接在Linux系统中,gcc是一种非常强大和常用的编译器,可以用于编译和链接C/C++程序。

本文将介绍一些gcc命令的高级技巧,以帮助读者更有效地使用gcc进行编译和链接。

1. 检查gcc版本要使用gcc命令,首先需要确保gcc已经正确安装在系统中。

可以使用以下命令检查gcc版本:```gcc --version```该命令会显示gcc的版本信息,以确保安装的gcc版本符合要求。

2. 编译单个源文件使用gcc编译单个源文件非常简单,只需使用以下命令:```gcc -o output_filename source_filename```其中,output_filename是编译生成的可执行文件的名称,source_filename是需要编译的源文件的名称。

例如,要编译名为`hello.c`的源文件并生成可执行文件`hello`,可以使用以下命令:```gcc -o hello hello.c```编译成功后,可以通过运行`./hello`命令执行生成的可执行文件。

3. 编译多个源文件对于包含多个源文件的项目,需要将多个源文件一起编译。

下面是一个示例命令:```gcc -o output_filename source_file1 source_file2 ... source_fileN```在这个命令中,只需将所有需要编译的源文件按顺序列出即可。

例如,要编译名为`main.c`和`helper.c`的两个源文件并生成可执行文件`program`,可以使用以下命令:```gcc -o program main.c helper.c```4. 自动编译所有源文件如果项目中的源文件比较多,手动编译每个源文件将会非常繁琐。

可以使用Makefile文件来自动编译所有源文件。

以下是一个简单的Makefile示例:```CC=gccCFLAGS=-call: programprogram: main.o helper.o$(CC) main.o helper.o -o programmain.o: main.c$(CC) $(CFLAGS) main.chelper.o: helper.c$(CC) $(CFLAGS) helper.cclean:rm -rf *.o program```在这个Makefile中,`CC`变量指定了编译器,`CFLAGS`变量指定了编译选项。

动态链接库及静态链接库(windows下的.dll.lib和linux下的.so.a)

动态链接库及静态链接库(windows下的.dll.lib和linux下的.so.a)

动态链接库‎及静态链接‎库(windo‎w s下的.dll .lib和l‎i nux下‎的.so .a)库有动态与‎静态两种,动态通常用‎.so为后缀‎,静态用.a为后缀。

例如:libhe‎l lo.so libhe‎l lo.a 为了在同一‎系统中使用‎不同版本的‎库,可以在库文‎件名后加上‎版本号为后‎缀,例如:libhe‎l lo.so.1.0,由于程序连‎接默认以.so为文件‎后缀名。

所以为了使‎用这些库,通常使用建‎立符号连接‎的方式。

ln -s libhe‎l lo.so.1.0 libhe‎l lo.so.1ln -s libhe‎l lo.so.1 libhe‎l lo.so使用库当要使用静态‎的程序库时‎,连接器会找‎出程序所需‎的函数,然后将它们‎拷贝到执行‎文件,由于这种拷‎贝是完整的‎,所以一旦连‎接成功,静态程序库‎也就不再需‎要了。

然而,对动态库而‎言,就不是这样‎。

动态库会在‎执行程序内‎留下一个标‎记…指明当程序‎执行时,首先必须载‎入这个库。

由于动态库‎节省空间,linux‎下进行连接‎的缺省操作是‎首先连接动‎态库,也就是说,如果同时存‎在静态和动‎态库,不特别指定‎的话,将与动态库‎相连接。

现在假设有‎一个叫he‎l lo的程‎序开发包,它提供一个‎静态库li‎b hell‎o.a 一个动态库‎l ibhe‎l lo.so,一个头文件‎h ello‎.h,头文件中提‎供sayh‎e llo()这个函数/* hello‎.h */void sayhe‎l lo();另外还有一‎些说明文档‎。

这一个典型‎的程序开发‎包结构1.与动态库连‎接linux‎默认的就是‎与动态库连‎接,下面这段程‎序test‎l ib.c使用he‎l lo库中‎的sayh‎e llo()函数/*testl‎i b.c*/#inclu‎d e#inclu‎d eint main(){sayhe‎l lo();retur‎n 0;}使用如下命‎令进行编译‎$gcc -c testl‎i b.c -o testl‎i b.o用如下命令‎连接:$gcc testl‎i b.o -lhell‎o -o testl‎i b在连接时要‎注意,假设lib‎h ello‎.o 和libh‎e llo.a都在缺省‎的库搜索路‎径下/usr/lib下,如果在其它‎位置要加上‎-L参数与与静态库‎连接麻烦一‎些,主要是参数‎问题。

linux中link指令的作用

linux中link指令的作用

linux中link指令的作用Link指令是Linux操作系统中的一个命令,它用于把程序模块彼此连接起来,形成一个可执行文件。

Link指令通常在C/C++编译器生成目标代码后被调用,将多个目标文件链接成一个可执行文件。

具体来说,Link指令分为静态链接和动态链接两种方式,下面分别进行介绍。

静态链接:当使用静态链接时,Link指令将目标文件中的符号表和函数库函数链接到生成的可执行文件中,可执行文件代码及数据都放在同一个文件中。

这种方式存在如下优点:1. 可执行文件不依赖于外部动态库,可移植性强;2. 不会受到动态库版本变化的影响;3. 由于所有代码都在一个文件中,执行时速度较快。

但是,静态链接也存在如下缺点:1. 可执行文件较大,尤其是包含多个静态库时;2. 由于每次编译都需要链接所有的库文件,因此编译时间较长;3. 如果多个程序都用到同一个库,静态链接会导致浪费更多的磁盘空间。

动态链接:当使用动态链接时,Link指令将库中的函数保存在独立的共享对象文件中,可执行文件包含一些用于定位和链接共享对象的信息。

这种方式存在如下优点:1. 可以节约磁盘空间,多个程序使用同一个共享库时只需要存储一份库文件;2. 内存中只需要加载一次库文件,所有使用该库的进程都可以共享该文件;3. 如果库文件更新,所有使用该库的程序都可以受益于更新的内容。

但是,动态链接也存在如下缺点:1. 执行速度较慢,因为需要在程序运行时寻找和加载共享库;2. 程序运行时可能会受到共享库版本的影响,如果共享库版本不匹配可能导致程序无法正常运行;3. 程序中出现不存在的库函数会导致运行时错误,难以调试。

总体来看,静态链接和动态链接各有优点和缺点,选择使用哪种链接方式应该根据具体的应用场景和需求来决定。

库技术 - Linux库详解

库技术 - Linux库详解

Linux库详解1 库基本概念1。

1 库的分类有两种说法,如果熟悉WIN平台下的DLL,相信不难理解:库可以有三种使用的形式:静态、共享和动态.静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。

动态库则是共享库的另一种变化形式.动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。

动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。

由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。

Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。

区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,静态链接库通常以。

a 结尾(Archive的缩写)。

在终端缺省情况下,共享库通常为绿色,而静态库为黑色。

已经开发的大多数库都采取共享库的方式。

ELF格式的可执行文件使得共享库能够比较容易地实现,当然使用旧的a.out模式也可以实现库的共享。

Linux系统中目前可执行文件的标准格式为ELF格式。

.a的是为了支持较老的a。

out格式的可执行文件的.so的是支持elf格式的可执行文件的库。

.a是静态库文件,可以用ar 命令生成.。

so是动态库文件,编译时加上指定的选项即可生成,具体选项看相应的系统文档了.1.2 库的命名规则GNU库的使用必须遵守Library GNU Public License(LGPL许可协议)。

该协议与GNU许可协议略有不同,开发人员可以免费使用GNU库进行软件开发,但必须保证向用户提供所用的库函数的源代码.库的命名和约定:(1)所以的库都以lib开头,许多开发工具都依赖这个约定,特别是GCC,它会在—l选项所指定的文件名前自动地插入lib。

静态链接库与动态链接库的创建方法和使用方法

静态链接库与动态链接库的创建方法和使用方法

静态链接库与动态链接库的创建方法和使用方法我折腾了好久静态链接库与动态链接库这事儿,总算找到点门道。

先说静态链接库吧。

我最开始尝试创建的时候,那真是一头雾水。

创建静态链接库一般是先要把相关的源文件写好,就像你要盖房子,先得把砖头啊材料什么的准备好。

在一些编程环境里,跟写普通的程序差不多,就是要讲究点组织方式。

比如说在C或者C++里,把要放进静态库的函数写在几个源文件里。

然后呢,用特定的编译命令。

我试过在Linux下,用GCC编译器。

我当时就犯了个错,没把编译选项搞对,就好像要盖房子,结果工具都拿错了,根本就没法顺利进行下去。

要生成静态链接库,就需要把这些源文件编译成目标文件,这一步就像把砖头初步加工一下。

然后通过一个叫归档工具的东西,就好比是把加工好的砖头整整齐齐地堆在一起,这个归档工具就可以把目标文件变成静态链接库文件了。

使用静态链接库的时候,就像搭积木。

要在你的主程序里包含头文件,这头文件就好比是搭积木的说明书,告诉主程序每个小零件(函数)怎么用。

然后在链接阶段,把静态库和主程序链接起来,这个过程如果搞错了,就像搭积木的时候,零件之间对不上。

动态链接库我一开始也觉得很复杂。

创建动态链接库,源文件的准备跟静态的有点类似,但编译的选项就大不同了。

如果把编译比作做饭,这个动态的编译选项就像是一组特殊的菜谱。

在Windows下用Visual Studio创建动态链接库的时候,图形界面操作看似简单,但里面那些设置很容易搞错,我当时不小心把导出函数的设置弄错了,就像你本来想把菜做熟了端上桌,结果菜还没做好就端上去了,程序一运行就出错。

使用动态链接库也是不容易的。

在程序里加载动态链接库就像是调用一个外援帮忙。

在不同系统上调用的方式还有差别。

在Linux下有一些特定的函数用于加载,像dlopen之类的。

我在这上面花了不少时间,最开始调用失败的时候,真是很沮丧。

得准确地告诉程序动态库在哪里,给的路径不对就好比你让朋友来帮忙,结果给错了地址,朋友找不到你。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

[Linux]链接,静态库和动态库Filename:[Linux]链接,静态库和动态库Version:V1.0Date:12/01/2009Author:S.C.Leon <leonsc@>============================================================== =======在Linux中创建静态库和动态库一、基本概念1.1什么是库在windows平台和linux平台下都大量存在着库。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

由于windows和linux的平台不同(主要是编译器、汇编器和连接器的不同),因此二者库的二进制是不兼容的。

本文仅限于介绍linux下的库。

1.2库的种类linux下的库有两种:静态库和共享库(动态库)。

二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

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

1.3库存在的意义库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

1.4库文件是如何产生的在linux下静态库的后缀是.a,它的产生分两步Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表Step 2.ar命令将很多.o转换成.a,成文静态库动态库的后缀是.so,它由gcc加特定参数编译产生。

具体方法参见后文实例。

1.5库文件是如何命名的,有没有什么规范在linux下,库文件一般放在/usr/lib和/lib下,静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号,minor是副版本号1.6如何知道一个可执行程序依赖哪些库ldd命令可以查看一个可执行程序依赖的共享库,例如# ldd /bin/lnlibc.so.6=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2=> /lib/ld- linux.so.2 (0×40000000)可以看到ln命令依赖于libc库和ld-linux库1.7可执行程序在执行的时候如何定位共享库文件当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径此时就需要系统动态载入器(dynamic linker/loader)对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib目录找到库文件后将其载入内存如:export LD_LIBRARY_PATH=’pwd’将当前文件目录添加为共享目录1.8在新安装一个库之后如何让系统能够找到他如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。

如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径2.运行ldconfig,该命令会重建/etc/ld.so.cache文件二、实验设计我们通常把一些公用函数制作成函数库,供其它程序使用。

函数库分为静态库和动态库两种。

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。

为了便于阐述,我们先做一部分准备工作。

2.1准备好测试代码hello.h、hello.c和main.c;hello.h(见程序1)为该函数库的头文件。

hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。

main.c(见程序3)为测试库文件的主程序,在主程序中调用了公用函数hello。

程序1: hello.hview plaincopy to clipboardprint?1.#ifndef HELLO_H2.#define HELLO_H3.4.void hello(const char *name);5.6.#endif //HELLO_H程序2: hello.cview plaincopy to clipboardprint?1.#include <stdio.h>2.3.4.5.void hello(const char *name)6.7.{8.9. printf("Hello %s!¥n", name);10.11.}程序3: main.cview plaincopy to clipboardprint?1.#include "hello.h"2.3.4.5. int main()6.7. {8.9. hello("everyone");10.11. return 0;12.13. }2.2问题的提出注意:这个时候,我们编译好的hello.o是无法通过gcc –o 编译的,这个道理非常简单,hello.c是一个没有main函数的.c程序,因此不够成一个完整的程序,如果使用gcc –o 编译并连接它,GCC将报错。

无论静态库,还是动态库,都是由.o文件创建的。

因此,我们必须将源程序hello.c 通过gcc先编译成.o文件。

这个时候我们有三种思路:1)通过编译多个源文件,直接将目标代码合成一个.o文件。

2)通过创建静态链接库libmyhello.a,使得main函数调用hello函数时可调用静态链接库。

3)通过创建动态链接库libmyhello.so,使得main函数调用hello函数时可调用静态链接库。

2.3思路一:编译多个源文件在系统提示符下键入以下命令得到hello.o文件。

# gcc -c hello.c为什么不适用gcc –o hello hello.c 这个道理我们之前已经说了,使用-c是什么意思呢?这涉及到gcc 编译选项的常识。

我们通常使用的gcc –o 是将.c源文件编译成为一个可执行的二进制代码,这包括调用作为GCC内的一部分真正的C编译器(ccl),以及调用GNU C编译器的输出中实际可执行代码的外部GNU汇编器和连接器工具。

而gcc –c是使用GNU汇编器将源文件转化为目标代码之后就结束,在这种情况下连接器并没有被执行,所以输出的目标文件不会包含作为Linux程序在被装载和执行时所必须的包含信息,但它可以在以后被连接到一个程序。

我们运行ls命令看看是否生存了hello.o文件。

# lshello.c hello.h hello.o main.c在ls命令结果中,我们看到了hello.o文件,本步操作完成。

同理编译main#gcc –c main.c将两个文件链接成一个.o文件。

#gcc –o hello hello.o main.o运行# ./helloHello everyone!完成^ ^!2.4思路二:静态链接库下面我们先来看看如何创建静态库,以及使用它。

静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。

例如:我们将创建的静态库名为myhello,则静态库文件名就是libmyhello.a。

在创建和使用静态库时,需要注意这点。

创建静态库用ar命令。

在系统提示符下键入以下命令将创建静态库文件libmyhello.a。

# ar cr libmyhello.a hello.o我们同样运行ls命令查看结果:# lshello.c hello.h hello.o libmyhello.a main.cls命令结果中有libmyhello.a。

静态库制作完了,如何使用它内部的函数呢?只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。

注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件。

在程序3:main.c中,我们包含了静态库的头文件hello.h,然后在主程序main中直接调用公用函数hello。

下面先生成目标程序hello,然后运行hello程序看看结果如何。

# gcc -o hello main.c -L. -lmyhello# ./helloHello everyone!我们删除静态库文件试试公用函数hello是否真的连接到目标文件hello中了。

# rm libmyhello.arm: remove regular file `libmyhello.a'? y# ./helloHello everyone!程序照常运行,静态库中的公用函数已经连接到目标文件中了。

2.5思路三、动态链接库我们继续看看如何在Linux中创建动态库。

我们还是从.o文件开始。

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但其文件扩展名为.so。

例如:我们将创建的动态库名为myhello,则动态库文件名就是libmyhello.so。

用gcc来创建动态库。

在系统提示符下键入以下命令得到动态库文件libmyhello.so。

# gcc -shared -fPCI -o libmyhello.so hello.o“PCI”命令行标记告诉GCC产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。

这样编译出的hello.o可以被用于建立共享链接库。

建立共享链接库只需要用GCC的”-shared”标记即可。

我们照样使用ls命令看看动态库文件是否生成。

# lshello.c hello.h hello.o libmyhello.so main.c调用动态链接库编译目标文件。

在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。

相关文档
最新文档