今天讲一下静态库的编译和使用吧。
静态库是在程序编译时直接将静态库编译进去,运行时不再需要将库的符号内容加载到内存,编译出来的程序占用空间也会变大。如果静态库修改了,就需要重新编译调用库的程序。
编译的话,直接就使用上次的代码进行编译:

gcc -c test_lib.c -o test_lib.o

ar crv libtest.a test_lib.o

可以用nm查看静态库中的符号表:

android中静态库报错 静态库编译_android中静态库报错


正是我们之前写的两个接口。这样就可以编译出静态库了。

怎么使用,我用一个github上的一个crc的库来进行简单的说明。

源码地址 https://github.com/lammertb/libcrc

下载直接make就可以编译出静态库以及代码中的一个测试文件,这里我们重新写。编译过程以及中间详细信息如下:

android中静态库报错 静态库编译_android中静态库报错_02


静态库符号表和头文件的内容差不多,这里不展示。直接将静态库和头文件拷贝到我们自己的代码路径下。创建test.c文件

#include <stdio.h>
#include "checksum.h"

int main(int argc, char **argv)
{
    FILE *fp = NULL;
    unsigned char prev_byte;
    unsigned int crc_32_val = 0;
    int ch;

    if (argc != 2) {
        printf("USAGE: ./file_crc file_name\n");
        return -1;
    }
    
    fp = fopen( argv[1], "rb" );
    if (NULL == fp) {
        printf("open file %s fail\n", argv[1]);
        return -1;
    }
    
    while( ( ch=fgetc( fp ) ) != EOF ) {
        crc_32_val = update_crc_32(crc_32_val, (unsigned char)ch);

        prev_byte = (unsigned char) ch;
    }
    
    printf("file %s crc = %u\n", argv[1], crc_32_val);
    
    fclose(fp);
    fp = NULL;
    
    return 0;
}

编译:

gcc test.c -I . -L . -lcrc

因为测试代码中写的是计算文件的crc,所以我们在代码目录下创建一个测试文件出来。

android中静态库报错 静态库编译_android中静态库报错_03


执行一下看看。

android中静态库报错 静态库编译_c语言_04


可以看出,当文件改变时,文件的crc校验值是改变的,同时我们静态库的使用也测试完成。

android中静态库报错 静态库编译_android中静态库报错_05


我们看下这几个文件,几行代码编译出的可执行文件a.out大小居然又11K字节,那是因为编译过程直接将crc的库包含进去了,所以文件占用会变大。

我之前的测试库,因为体积太小,动态库和静态库编译出的可执行文件基本没差。后续大伙可能在交叉开发中,遇到这种情况,考虑裁剪flash的时候,可以综合考虑两种编译方式,再决定最终是使用动态库或静态库。