动态编译和静态编译

image.png
image.png

makefile:

  1. dynamic: dynamic.c
  2. gcc -g $^ -o $@
  3. static: static.c
  4. gcc -g $^ -static -o $@

dynamic.c和static.c:

  1. #include<stdio.h>
  2. int main(){
  3. printf("hello world\n");
  4. return 0;
  5. }

image.png

动态链接库的加载时机

image.png

链接(编译)时加载

image.png
image.png
makefile:

all:libfun.so dynamic_load
    #
libfun.so:/tools/fun.c
    gcc $^ -g -shared -fPIC  -o $@
dynamic_load.so:dynamic_load.c
    gcc $^ -g -L. -lfun -o $@

fun.c:

#include"fun.h"

int add(int a,int b){
    return a+b;
}

dynamic_load.c:

#include<stdio.h>
#include"tools/fun.h"
int main(){
    printf("number = %d\n",add(1,2));
    return 0;
}

image.png

运行时加载

image.png
makefile

run_load:run_load.c
    gcc $^ -g -ldl -o $@

run_load.c(需要上面的libfun.so文件)

#include<unistd.h>
#include<stdio.h>
#include<dlfcn.h>
//编译时需要使用 -ldl动态库  libdl.so
int add(int a,int b);
//定义函数指针
typedef int (*PFUN)(int,int);

//运行时动态加载so文件
int main(){
    //1、加载so文件
    void * handle = dlopen("./libfun.so",RTLD_LAZY);//延时加载
    if(handle==NULL){
        printf("dlopen error :%s\n",dlerror());
        return 0;
    }
    //2、解析符号,获取so文件中的函数(变量)
    PFUN pfun = (PFUN)dlsym(handle,"add");
    if(handle==NULL){
        printf("dlopen error :%s\n",dlerror());
        return 0;
    }
    //3、使用这个函数(变量)
    int number = pfun(10,20);
    printf("number = %d\n",number);

    //4、卸载so文件
    dlclose(handle);
    return 0;
}

image.png

so加载顺序

image.png

动态链接库加载流程

image.png