您的位置:首页 > 运维架构 > Linux

linux简单实现静态链接和动态链接

2018-02-26 02:35 302 查看
在给别人发送文件的时候,如果我们只想让别人调用功能而已,不想自己的源代码公布出去,我们可以选择将文件做成一个库,直接供别人调用就可以了。
这样的话,在网络上分享自己的劳动成果的话,只要发送一个链接库和对应的头文件(.h)就足以(前提是确保代码已经千锤百炼过,不然除了问题别人没办法解决)。
静态库和动态库
static静态库  :一般名字是libxxx.a;
shared动态库:一般名字是libxxx.so;
Windows下:.dll文件
静态库制作:
[yan@localhost c_work]$ gcc -c file1.c          
                   
           //生成一个file.o的文件
[yan@localhost c_work]$ gcc -c file2.c
[yan@localhost c_work]$ ar -rcs libname.a file1.o file2.o ...         
//打包生成一个libname.a的静态库
//-r:replace,当插入的模块已经存在,则替换同名模块;若不存在,返回一个错误;默认新增加的在文件尾。
//-c:create
//-s:static
动态库制作:
[yan@localhost c_work]$ gcc -shared -fpic -o libname.so file1.c file2.c ...        //生成一个libname.so的动态库
//-shared:生成动态库
//-fpic:产生代码位置无关于代码

静态库制作示例
//add.c

[yan@localhost src]$ cat add.c
#include <stdio.h>
int add(int a,int b)
{
    return a+b;
} /* ----- End of add()  ----- *

//sub.c

[yan@localhost src]$ cat sub.c
#include <stdio.h>
int sub(int a,int b)
{
    return a-b;
} /* ----- End of sub()  ----- *

//mul.c

[yan@localhost src]$ cat add.c
#include <stdio.h>
int

mul(int a,int b)
{
    return a*b;
} /* ----- End of

mul()  ----- *

//fun.h

[yan@localhost src]$ cat fun.h
#ifndef __FUN_H_
#define __FUN_H_
extern add(int a,int b);
extern sub(int a,int b);
extern mul(int a,int b);
#endif

//main.c

[yan@localhost src]$ cat main.c
#include <fun.h>
#include <stdio.h>
int main (int argc, char **argv)
{
    int  a = 15;
    int  b = 10;
    printf("a = %d,b = %d\n",a,b);
    
    printf("a + b = %d\n",add(a,b));
    printf("a  - b = %d\n",sub(a,b));
    printf("a * b = %d\n",mul(a,b));
    
    return 0;
} /* ----- End of main() ----- */

//生成静态库

[yan@localhost src]$ ls
add.c  fun.h  main.c  mul.c  sub.c
[yan@localhost src]$

gcc -c *.c
main.c:1:17: error: fun.h: No such file or directory
[yan@localhost src]$ ls
add.c  add.o  fun.h  main.c  mul.c  mul.o  sub.c  sub.o
[yan@localhost src]$

ar -rcs libfun.a *.o
[yan@localhost src]$ ls
add.c  add.o  fun.h  libfun.a  main.c  mul.c  mul.o  sub.c  sub.o

//静态链接

[yan@localhost src]$ gcc main.c
main.c:1:17: error: fun.h: No such file or directory
找不到头文件
-I(大写i):指定头文件路径
[yan@localhost src]$

gcc -I .  main.c  
/tmp/ccRKZULI.o: In function `main':
main.c:(.text+0x42): undefined reference to `add'
main.c:(.text+0x67): undefined reference to `sub'
main.c:(.text+0x8c): undefined reference to `mul'
collect2: ld returned 1 exit status
未找到链接库
-L:指定链接库的位置
-l(小写L):指定链接库的名字,去掉lib和.a和.so
[yan@localhost src]$

gcc main.c -I ./ -L ./ -l fun -o afun 

 //main的位置最好放在前面不然会被认为和库同级
[yan@localhost src]$ ls
add.c

afun
 fun.h  libfun.a   main.c
 mul.c  sub.c

//静态链接后可直接执行

[yan@localhost src]$ ./afun
a = 15,b = 10
a + b = 25
a - b = 5
a * b = 150

动态库制作示例
//生成动态库,把main.c先移出去

[yan@localhost src]$ ls
add.c  fun.h mul.c  sub.c
[yan@localhost src]$

gcc -shared -fpic -o libfun.so *.c
[yan@localhost src]$ ls
add.c  fun.h libfun.a  libfun.so  mul.c  sub.c

//当动态和静态库同时存在时进行链接

[yan@localhost src]$ ls
add.c fun.h  libfun.a libfun.so 

main.c  mul.c  sub.c
[yan@localhost src]$

gcc main.c -I ./ -L ./ -l fun -o afun     //如要静态编译,可以加-static
[yan@localhost src]$ ./afun
./afun: error while loading shared libraries:
libfun.so: cannot open shared object file: No such file or directory

//可以看出程序链接时优先动态链接
//动态链接的程序执行时,需要指定动态库的位置
2种指定动态库位置的方法:
1.将库放到/lib或者/usr/lib下(需要root权限)
2.添加环境变量LD_LIBRARY_PATH

[yan@localhost src]$ echo $LD_LIBRARY_PATH
//原来的LD_LIBRARY_PATH为空,现在添加,比如当前路径
[yan@localhost src]$

export LD_LIBRARY_PATH=`pwd`
[yan@localhost src]$ echo $LD_LIBRARY_PATH       
/home/yan/c_work/src
[yan@localhost src]$ ./afun
a = 15,b = 10
a + b = 25
a - b = 5
a * b = 150

file    ldd
file查看文件类型

[yan@localhost src]$ file afun
afun: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

ldd查看文件所依赖的动态库
//静态库链接没有动态库所以不显示

[yan@localhost src]$ ldd afun
        linux-vdso.so.1 =>  (0x00007ffcbf2df000)
        libfun.so => /home/yan/c_work/src/libfun.so (0x00007fc97d6c2000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003929000000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003928c00000)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux c语言