大连建立网站公司,wordpress网盘引擎,如何用代码做分数查询的网站,有哪些学做衣服的网站在Linux操作系统中#xff0c;普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式。ELF#xff08;Executable and Linking Format#xff0c;可执行连接格式#xff09;。 ELF文件格式包括三种主要的类型#xff1a;可执行文件、可重定向文件、共享库#xff1… 在Linux操作系统中普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式。ELFExecutable and Linking Format可执行连接格式。 ELF文件格式包括三种主要的类型可执行文件、可重定向文件、共享库 1、可执行文件应用程序 可执行文件包含了代码和数据是可以直接运行的程序。 2、可重定向文件*.o 可重定向文件又称为目标文件它包含了代码和数据这些数据是和其他重定位文件和共享的object文件一起连接时使用的。 *.o文件参与程序的连接创建一个程序和程序的执行运行一个程序它提供了一个方便有效的方法来用并行的视角看待文件的内容这些*.o文件的活动可以反映出不同的需要。 Linux下我们可以用gcc -c编译源文件时可将其编译成*.o格式。 3、共享文件*.so 也称为动态库文件它包含了代码和数据这些数据是在连接时候被连接器ld和运行时动态连接器使用的。动态连接器可能称为ld.so.1libc.so.1或者 ld-linux.so.1。 那么到底什么是库呢 库从本质上来说是一种可执行代码的二进制格式可以被载入内存中执行。库分静态库和动态库两种。二者的不同点在于代码被载入的时刻不同。 静态库这类库的名字一般是libxxx.axxx为库的名字。静态库在程序编译时会被连接到目标代码中利用静态函数库编译成的文件比较大因为整个函数库的所有数据都会被整合进目标代码中他的优点就显而易见了即编译后的执行程序不需要外部的函数库支持因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点因为如果静态函数库改变了那么你的程序必须重新编译。 动态库这类库的名字一般是libxxx.M.N.so同样的xxx为库的名字M是库的主版本号N是库的副版本号。当然也可以不要版本号但名字必须有。相对于静态函数库动态函数库在编译的时候并没有被编译进目标代码中你的程序执行到相关函数时才调用该函数库里的相应函数因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序而是程序运行时动态的申请并调用所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序所以动态函数库的升级比较方便。linux系统有几个重要的目录存放相应的函数库如/lib /usr/lib。 当要使用静态的程序库时连接器会找出程序所需的函数然后将它们拷贝到执行文件由于这种拷贝是完整的所以一旦连接成功静态程序库也就不再需要了。然而对动态库而言就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时首先必须载入这个库。由于动态库节省空间linux下进行连接的缺省操作是首先连接动态库也就是说如果同时存在静态和动态库不特别指定的话将与动态库相连接。 一、静态库 前面已经介绍了静态库的概念下面我们通过一个实例来看静态库的使用 1、生成静态库 1这里准备了两个库的源码st1 、st2用它们来制作库libmytest.a如下 [cpp] view plaincopy fsubuntu:~/qiang/stalib$ ls -l total 12 -rw-rw-r-- 1 fs fs 98 Jan 5 19:56 main.c -rw-rw-r-- 1 fs fs 69 Jan 5 19:55 st1.c -rw-rw-r-- 1 fs fs 68 Jan 5 19:55 st2.c fsubuntu:~/qiang/stalib$ cat st1.c #include stdio.h void print1() { printf(Hello!I am st1!\n ); } fsubuntu:~/qiang/stalib$ cat st2.c #include stdio.h void print2() { printf(Hello!I am st2!\n); } fsubuntu:~/qiang/stalib$ cat main.c #include stdio.h int main(int argc, const char *argv[]) { print1(); print2(); return 0; } fsubuntu:~/qiang/stalib$ 2) 生成libmytest.a文件 创建静态库用ar命令它将很多.o转换成.a [cpp] view plaincopy fsubuntu:~/qiang/stalib$ gcc -c st1.c st2.c fsubuntu:~/qiang/stalib$ ar crs libmytest.a st1.o st2.o fsubuntu:~/qiang/stalib$ ls -l total 24 -rw-rw-r-- 1 fs fs 2262 Jan 5 20:04 libmytest.a -rw-rw-r-- 1 fs fs 98 Jan 5 19:56 main.c -rw-rw-r-- 1 fs fs 69 Jan 5 20:03 st1.c -rw-rw-r-- 1 fs fs 1024 Jan 5 20:04 st1.o -rw-rw-r-- 1 fs fs 69 Jan 5 20:03 st2.c -rw-rw-r-- 1 fs fs 1024 Jan 5 20:04 st2.o fsubuntu:~/qiang/stalib$ file libmytest.a libmytest.a: current ar archive fsubuntu:~/qiang/stalib$ 静态库文件libmytest.a已经生成用file命令查看其属性发现它确实是归档压缩文件。用ar -t libmytest.a可以查看一个静态库包含了那些obj文件 [cpp] view plaincopy fsubuntu:~/qiang/stalib$ ar -t libmytest.a st1.o st2.o fsubuntu:~/qiang/stalib$ 2、使用静态库 前面我们已经写好了main.c现在测试一下 [cpp] view plaincopy fsubuntu:~/qiang/stalib$ gcc -o test main.c -L. -lmytest fsubuntu:~/qiang/stalib$ ls -l total 32 -rw-rw-r-- 1 fs fs 2262 Jan 5 20:04 libmytest.a -rw-rw-r-- 1 fs fs 98 Jan 5 19:56 main.c -rw-rw-r-- 1 fs fs 69 Jan 5 20:03 st1.c -rw-rw-r-- 1 fs fs 1024 Jan 5 20:04 st1.o -rw-rw-r-- 1 fs fs 69 Jan 5 20:03 st2.c -rw-rw-r-- 1 fs fs 1024 Jan 5 20:04 st2.o -rwxrwxr-x 1 fs fs 7248 Jan 5 20:07 test fsubuntu:~/qiang/stalib$ ./test Hello! I am st1! Hello! I am st2! fsubuntu:~/qiang/stalib$ 这里gcc的参数-L是告诉编译器库文件的路径是当前目录-l是告诉编译器要使用的库的名字叫mytest。 二、动态库 动态库的基本概念 1、动态链接库是程序运行时加载的库当动态链接库正确安装后所有的程序都可以使用动态库来运行程序。动态链接库是目标文件的集合目标文件在动态链接库中的组织方式是按照特殊方式形成的。库中函数和变量的地址是相对地址不是绝对地址其真实地址在调用动态库的程序加载时形成。 2、动态链接库的名称有别名soname, 真名(realname)和链接名linker name。别名由一个前缀lib,然后是库的名字再加上一个后缀“.so”构成(libxxx.so)。真名是动态链接库真实名称一般总是在别名的基础加上一个小版本号发布版本等构成。除此之外还有一个链接名即程序链接时使用的库的名字。 3、在动态链接库安装的时候总是复制文件到某个目录下然后用一个软连接生成别名在库文件进行更新的时候仅仅更新软链接即可。 下面我们通过一个实例来学习如何生成动态库和使用动态库 1、生成动态库 1当前文件夹下有下面四个文件 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ls -l total 16 -rw-rw-r-- 1 fs fs 73 Jan 5 18:11 dy1.c -rw-rw-r-- 1 fs fs 74 Jan 5 18:11 dy2.c -rw-rw-r-- 1 fs fs 90 Jan 5 18:11 main.c -rw-rw-r-- 1 fs fs 95 Jan 5 18:10 mylib.h fsubuntu:~/qiang/lib/dylib$ 文件内容分别为 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ cat mylib.h #ifndef _MYLIB_H_ #define _MYLIB_H_ #include stdio.h void print1(); void print2(); #endif fsubuntu:~/qiang/lib/dylib$ cat dy1.c #include mylib.h void print1() { printf(My first shared lib!\n); } fsubuntu:~/qiang/lib/dylib$ cat dy2.c #include mylib.h void print2() { printf(My second shared lib!\n); } fsubuntu:~/qiang/lib/dylib$ cat main.c #include mylib.h int main(int argc, char *argv[]) { print1(); print2(); return 0; } fsubuntu:~/qiang/lib/dylib$ 2这里我们将dy1.c与dy2.c用来创建动态库 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ gcc -fPIC -Wall -c dy1.c dy2.c fsubuntu:~/qiang/lib/dylib$ gcc -shared -o libtest.so dy1.o dy2.o fsubuntu:~/qiang/lib/dylib$ 这里 -fPIC 创建与地址无关的编译程序-shared指定生成动态链接库。 我们也可以一步到位 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ gcc -o libtest.so -fPIC -shared dy1.c dy2.c fsubuntu:~/qiang/lib/dylib$ 我们可以看到下面已经生成了一个libtest.so [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ls -l total 32 -rw-rw-r-- 1 fs fs 73 Jan 5 18:11 dy1.c -rw-rw-r-- 1 fs fs 1332 Jan 5 18:29 dy1.o -rw-rw-r-- 1 fs fs 74 Jan 5 18:11 dy2.c -rw-rw-r-- 1 fs fs 1336 Jan 5 18:29 dy2.o -rwxrwxr-x 1 fs fs 6798 Jan 5 18:29 libtest.so -rw-rw-r-- 1 fs fs 90 Jan 5 18:11 main.c -rw-rw-r-- 1 fs fs 95 Jan 5 18:10 mylib.h fsubuntu:~/qiang/lib/dylib$ 2、使用动态链接库 在编译程序时使用动态链接库和静态库是一致的使用”-l库名”的方式在生成可执行文件的时候会链接库文件。使用如下命令 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ gcc -o test main.c -L. -ltest fsubuntu:~/qiang/lib/dylib$ ls dy1.c dy2.c libtest.so main.c mylib.h test 这里 -L 指定动态链接库的路劲-ldtest链接库函数test 。-ltest是动态库的调用规则。Linux系统下的动态库命名方式是lib*.so,而在链接时表示位-l*,*是自己命名的库名。 我们可以看到这里已经生成了test可执行文件我们可以执行一下 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ./test ./test: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory fsubuntu:~/qiang/lib/dylib$ 可以发现发生了错误这是因为程序运行时没有找到动态链接库造成的。程序编译时链接动态库和运行时使用动态链接库的概念是不同的在运行时程序链接的动态链接库需要在系统目录下才行。 这就到了动态库的路径问题有三种方法 1把库拷贝到/usr/lib和/lib目录下 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ sudo cp libtest.so /lib [sudo] password for fs: 这里要超级用户权限sudo,我们看一下执行结果 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ./test My first shared lib! My second shared lib! fsubuntu:~/qiang/lib/dylib$ 这里执行结果正确。 2在 LD_LIBRARY_PATH 环境变量中加上库所在路径 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ export LD_LIBRARY_PATHpwd:$LD_LIBRARY_PATH fsubuntu:~/qiang/lib/dylib$ 我们可以看到libtest.so 的路径已经存在 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ldd test linux-gate.so.1 (0xb774b000) libtest.so /home/fs/qiang/lib/dylib/libtest.so (0xb7746000) libc.so.6 /lib/i386-linux-gnu/libc.so.6 (0xb758d000) /lib/ld-linux.so.2 (0xb774c000) fsubuntu:~/qiang/lib/dylib$ 我们可以看一下结果 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ ./test My first shared lib! My second shared lib! fsubuntu:~/qiang/lib/dylib$ 也能得到正确结果。 3添加/etc/ld.so.conf.d/*.conf文件。把库所在的路径加到文件末尾并执行ldconfig刷新。 [cpp] view plaincopy fsubuntu:~/qiang/lib/dylib$ cd /etc/ld.so.conf.d/ fsubuntu:/etc/ld.so.conf.d$ ls i386-linux-gnu_GL.conf libc.conf i686-linux-gnu.conf vmware-tools-libraries.conf fsubuntu:/etc/ld.so.conf.d$ sudo vi my.conf [sudo] password for fs: fsubuntu:/etc/ld.so.conf.d$ cat my.conf /home/fs/qiang/lib/dylib/libtest.so fsubuntu:/etc/ld.so.conf.d$ 在/etc/ld.so.conf.d/下建立 my.conf 里面只有一句/home/fs/qiang/lib/dylib/libtest.so 即libtest.so的路径然后执行ldconfig刷新即可。