C语言静态库和动态库

实现文件共享

例子:
目录结构如下:
|--myHeader
  --checksum.h
  --encrypt.h
|--checksum.c
|--encrypt.c
|--test.c
|--myObject

在myHeader文件中建立头文件checksum.h
int checksum(char *message);
在myHeader文件中建立头文件encrypt.h
void encrypt(char *message);

checksum.c内容:
#include <checksum.h>

int checksum(char *message)
{
 int c = 0;
 while (*message) {
     c += c ^ (int)(*message);
     message++;
 }

 return c;
}

encrypt.c内容:
#include "./myHeader/encrypt.h"

void encrypt(char *message)
{
 char c;
 while(*message) {
     *message = *message ^ 31;
     message++;
 }
}

test.c的内容:
#include <stdio.h>
#include "./myHeader/encrypt.h"
#include "./myHeader/checksum.h"

int main()
{
     char s[] = "Speak friend and enter";
     encrypt(s);
     printf("Encrypt to '%s'\n", s);
     printf("checksum is %i\n", checksum(s));
     encrypt(s);
     printf("Decrypt to '%s'\n", s);
     printf("checksum is %i\n", checksum(s));
     return 0;
}

/*
    把头文件和编译后的文件都保存在固定的文件中方便共享(myHeader和myObject)
    -I告诉编译器去哪里找头文件
*/
执行命令:(执行命令每次都要指定.o的文件路径,是不是太麻烦?)
    gcc -I ./myHeader -c checksum.c -o ./myObject/checksum.o
    gcc -I ./myHeader -c encrypt.c -o ./myObject/encrypt.o
    gcc -I ./myHeader test.c ./myObject/checksum.o ./myObject/encrypt.o -o test && ./test

创建静态库的方式

/*
    r:如果.a文件存在就更新它
    c:表示创建存档时不显示反馈信息
    s:告诉ar要在.a文件开头建立索引
    创建的文件名:libhfsecurity.a
    ** 静态库名字的命名规范一般是:libxxx.a的形式,不然编译器无法找到它
*/
ar -rcs libhfsecurity.a encrypt.o checksum.o

/*
    可以查看.a文件是由那些文件组成
*/
ar -t libhfsecurity.a

/*
    lhfsecurity对应去寻找上面创建的静态库的名字:libhfsecurity.a
    -I指定头文件位置
    -L告诉编译器去哪寻找存档
    当然如果你把.a的文件放在/usr/local/lib(用来存放本地自定义库或者系统类库/usr/lib)中,可以不指定-L参数
    gcc test.c  -lhfsecurity -o test
*/
gcc -I ./myHeader test.c -L myObject -lhfsecurity -o test && ./test

静态库例子

目录结构:
|--myHeader
  --hfcal.h
|--myObject
|--treadmill
  --elliptical.c
  --hfcal.c

hfcal.h中的内容:
    void display_calories(float weight, float distance, float coeff);

hfcal.c文件中的内容:
    #include <stdio.h>
    #include <hfcal.h>

    void display_calories(float weight, float distance, float coeff)
    {
        printf("Weight:%3.2f lbs\n", weight);
        printf("Distance:%3.2f miles\n", distance);
        printf("Calories burned:%4.2f cal\n", coeff * weight * distance);
    }

elliptical.c文件中的内容:
    #include <stdio.h>
    #include <hfcal.h>

    int main()
    {
        display_calories(115.2, 11.3, 0.79);
        return 0;
    }

cd treadmill
gcc -I ../myHeader -c hfcal.c -o ../myObject/hfcal.o
gcc -I ../myHeader -c elliptical.c -o ../myObject/elliptical.o
ar -rcs ../myObject/libhfcal.a ../myObject/hfcal.o
cd ../myObject
gcc elliptical.o -L ./ -lhfcal -o elliptical

创建动态库

/*
    -I指定头文件目录,-c不要链接代码,-fPIC创建位置无关代码创建库
*/
gcc -I ../myHeader -fPIC -c hfcal.c -o ../myObject/hfcal.o

/*
    --shared告诉gcc把目标文件转化为动态库
    动态库在每个系统的后缀名都不一样
    windows中后缀名是.dll
    在linux和unix尚后缀名是.so
   在mac上后缀名是是.dylib
*/
cd ../myObject/


/*
    在一些稍微老一点的mac系统上,没有-shared选项,可以使用-dynamiclib代替
*/
                        libhfcal.dll.a      #windows上的cygwin
                        libhfcal.dylib         #mac
gcc -shared hfcal.o -o  hfcal.dll           #windows上的mingw
                        libhfcal.so         #linux或unix

cd ../treadmill/
gcc -I ../myHeader -c elliptical.c -o ../myObject/elliptical.o
cd ../myObject/

/*
    在linux和大部分unix中,编译器只会记录libhfcal.so库的文件名,而不会包含路径名,也就是说如果不把hfcal库保存到标准目录(/usr/lib),程序就找不到它
    一般解决方法是:把库目录添加到LD_LIBRARY_PATH中,并export它
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
*/
gcc elliptical.o -L ./ -lhfcal -o elliptical
坚持原创技术分享,您的支持将鼓励我继续创作!