Linux编译动态库和静态库编译过程,动态库的动态加载

1、前言

为什么要用库文件?大家写代码要用printf函数,包含stdio.h就可以用了,这就是调用了C库中的函数,比较通用的东西可以制作成库给大家使用。还有项目开发的时候,尤其是跨公司合作开发,源码不能随便给,我就把我的代码模块制作成库文件给你,你的代码加载我的库文件就可以生成方便调试你代码的应用程序。

2、静态编译

静态编译是把库文件合并进应用程序,好处就是换个设备可以直接运行,不和动态库一样还得将应用程序和库文件同时移动到新设备才能用。

2.1 编译静态库

mylib.c中保存下面的简单代码,提供了一个打印函数:

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

void LibTest()
{
    printf("Exe LibTest In mylib.c\n");
}

对应的mylib.h文件如下:

#ifndef __MY_LIB_H__
#define __MY_LIB_H__

extern void LibTest(void);

#endif

将该.c文件编译为.o文件,执行命令:

gcc -c mylib.c -o mylib.o

编译生成静态库文件,执行命令:

ar -r libmylib.a mylib.o

其中-r表示创建新的库文件mylib.a并将mylib.o添加进去

2.2 使用静态库

在main.c文件中调用静态库文件中的代码:

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

int main()
{
    LibTest();
    
    return 0;
}

编译可执行程序:

gcc -o app main.c -L ./ -lmylib -static

其中,-L指定静态库的路径 -l指定静态库的名称,此处libmylib不需要加前面的lib,-static指定静态编译。

编译完成的app程序可以直接手动发起运行,运行结果如下:

3、动态编译

动态库在程序运行的时候实时加载,不需要编译进应用程序,这样做的好处是减少应用程序的体积,坏处就是移动程序的时候需要对应移动动态库。

3.1 编译动态库

还使用上面的代码,执行以下命令生成动态库文件:

gcc mylib.c -fPIC -shared -o libmylib.so

其中-fPIC表示生成位置无关代码,-shared表示生成动态库文件

3.2 使用动态库

将动态库拷贝至/usr/lib:

cp libmylib.so /usr/lib

编译可执行程序:

gcc -o appDT main.c -L. -lmylib

编译出来的程序直接运行即可,考虑访问库文件的权限,加sudo运行:

 3.3 体积比较

对比编译静态库的可执行程序和动态库的可执行程序大小,可以验证前面的说法:

 3.4 动态库的动态加载使用

动态加载调用代码如下:

#include <stdio.h>
#include <dlfcn.h>

typedef void (*pJustPtf)(void);

int main()
{
    void * handle = NULL;
    pJustPtf  ptf = NULL;

    // 打开当前目录下的so库文件
    handle = dlopen ("./libmylib.so", RTLD_LAZY);

    if(handle != NULL)
    {
        // 从库文件中查找LibTest函数
        ptf = dlsym(handle, "LibTest");

        // 调用LibTest函数
        ptf();
    }
    
    return 0;
}

使用以下命令编译可执行程序:

gcc main.c -o app123 -ldl

直接运行即可:

猜你喜欢

转载自blog.csdn.net/cesheng3410/article/details/129439035
今日推荐