静态链接库,动态链接库

    xiaoxiao2022-06-25  218

    关于静态链接库,参考如下博文:

    https://blog.csdn.net/llisq/article/details/50247907

    ---------------------------------------------------------------------

    当你完成了代码开发,想把这个代码给别人用,但是又不希望别人看到源码,就要给别人一个库和头文件,库和头文件是配合的,缺一不可。

    或者过程相反,你从别人那里拿到一个库和头文件来使用。

    那么如何编译生成一个库给他人,如何使用从他人那里拿到的库呢?

    范例1:我们想把LinuxFrame.c和LinuxFrame.h这两个文件生产库给用户

    #LinuxFrame.c

    #include "stdio.h"

    #include "LinuxFrame.h"

    void LoadBootCodeFromExDisk();

    //ORG 0x30000

    void startkernel(){

        LoadBootCodeFromExDisk();

    }

    void LoadBootCodeFromExDisk()

    {

        printf("abcdefg\n");

    }

    #LinuxFrame.h

    #ifndef ____LinuxFrame__

    #define ____LinuxFrame__

    #include <stdio.h>

    void startkernel();

    #endif /* defined(____LinuxFrame__) */

    一、对象文件

    利用如下方法

    #gcc -c LinuxFrame.c

    生成一个对象文件LinuxFrame.o。把这个LinuxFrame.o文件和LinuxFrame.h文件提供给用户。

    用户使用如下main.c程序就可以调用LinuxFrame.c中的startkernel函数,从而使用startkernel功能。

    #main.c

    #include "LinuxFrame.h"

    int main()

    {

        startkernel();

    }

    使用方法如下: #gcc -o main main.c LinuxFrame.o

    于是就可以生成一个可执行文件main。

    注意main.c中使用了LinuxFrame.h,在链接的时候使用了LinuxFrame.o。

    那么看起来LinuxFrame.o就可以了,为什么还要库呢?

    一、生成库文件

    以下指令会把LinuxFrame.o生成LinuxFrame.a。.a的意思是archive,是档案的意思。

    #ar cr LinxFrame.a LinuxFrame.o

    用户拿到你的LinuxFrame.a和LinuxFrame.h后,可以用这样的方法来生成可执行文件main使用:

    #gcc -o main main.c LinuxFrame.a

    上述语句生产可执行文件main。

    执行main

    #./main

    输出

    #abcdefg

    这样看起来LinuxFrame.a和LinuxFrame.o是一样的。

    但是库文件比对象文件功能还强大一点,比如还有一个c文件fs.c

    #fs.c

    #include "stdio.h"

    #include "LinuxFrame.h"

    void createfs(){

        printf("file system\n");

    }

    你可以 $ gcc -c fs.c

    再生产一个fs.o对象文件。 然后 $ar -r LinuxFrame.a LinuxFrame.o fs.o

    生成一个库文件LinuxFrame.a 把原来的main.c改成: #main.c #include "LinuxFrame.h"

    int main()

    {

        startkernel();

        fs();

    }

    然后: $gcc -o main main.c LinuxFrame.a

    这个时候生产可执行文件main

    $./main

    输出

    $abcdefg

    $file system

    库文件相比.o文件的好处是库文件可以包含很多个.o文件。  

    --------------------------------------------------------------------------------------------------------------

    关于动态库文件的生成与使用,参见以下博文:

    https://blog.csdn.net/lisayh/article/details/79726249

     

    编辑四个文件:A1.c  A2.c  A.h test.c

    A1.c:

    #include <stdio.h> void print1(int arg){ printf("A1 print arg:%d\n",arg); }

    A2.c:

    #include <stdio.h> void print2(char *arg){ printf("A2 printf arg:%s\n", arg); }

    A.h

    #ifndef A_H #define A_H void print1(int); void print2(char *); #endif

    test.c:

    #include <stdlib.h> #include "A.h" int main(){ print1(1); print2("test"); exit(0); }

    1、静态库.a文件的生成与使用。

    1.1、生成目标文件(xxx.o)

    ---> gcc -c A1.c A2.c

    1.2、生成静态库.a文件

    ---> ar crv libafile.a A1.o A2.o

    1.3、使用.a库文件,创建可执行程序(若采用此种方式,需保证生成的.a文件与.c文件保存在同一目录下,即都在当前目录下)

    ---> gcc -o test test.c libafile.a

    ---> ./test

    2、共享库.so文件的生成与使用

    2.1、生成目标文件(xxx.o)(此处生成.o文件必须添加"-fpic"(小模式,代码少),否则在生成.so文件时会出错)

    ---> gcc -c -fpic A1.c  A2.c

    2.2、生成共享库.so文件

    ---> gcc -shared *.o -o libsofile.so

    2.3、使用.so库文件,创建可执行程序

    ---> gcc -o test test.c libsofile.so

    ---> ./test

    发现出现错误:

    ./test: error while loading shared libraries: libsofile.so: cannot open shared object file: No such file or directory

    运行ldd test,查看链接情况

    ldd test     linux-vdso.so.1 =>  (0x00007fff0fd95000)     libsofile.so => not found     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f937b5de000)     /lib64/ld-linux-x86-64.so.2 (0x0000563f7028c000) 发现确实是找不到对应的.so文件。

    这是由于linux自身系统设定的相应的设置的原因,即其只在/lib and /usr/lib下搜索对应的.so文件,故需将对应so文件拷贝到对应路径。

    --->sudo cp libsofile.so /usr/lib

    再次执行./test,即可成功运行。

    ---> ./test

    同时可直接使用gcc -o test test.c -L. -lname,来使用相应库文件

    其中,

            -L.:表示在当前目录下,可自行定义路径path,即使用-Lpath即可。

          -lname:name:即对应库文件的名字(除开lib),即若使用libafile.a,则name为afile;若要使用libsofile.so,则name为sofile)。


    最新回复(0)