VScode配置C/C++环境
- 静态库和动态库的基本概念
- 静态库和动态库的创建
- 静态库和动态库的使用
- Makefile写法
一、静态库和动态库的基本概念
静态库和动态库简单理解就是对目标文件的打包操作
1.1 静态库
一般情况下的静态库命名规则:
- lib开头
- .lib结尾 —>Windows
- .a结尾 —>Linux
例如:
- libxxx.lib 的名字就是xxx
- libyyy.a 的名字就是yyy
在Windows下.lib和.a都可以表示静态库,但是使用的时候
- .lib的静态库需要用lib加名字
- .a的静态库只需要用名字
静态库的特点:
- 编译阶段完成
- 在链接的时候把静态库的**“内容”**放到最终的可执行文件中
- 静态库一旦嵌到可执行文件中就可以直接运行程序,静态库和程序本身再无关系
- 把静态库嵌入到可执行文件中会使可执行文件的体积变大
lib: library 库
a : archive 档案
1.2 动态库
动态库:有**“动态链接库”和“共享对象”**的叫法。
一般情况下的动态库命名规则:
- lib开头
- .dll结尾 —>Windows
- .so结尾 ---->Linux
例如:
- libxxx.dll 是名为xxx的动态库
- libyyy.so 是名为yyy的动态库
DLL: Dynamic Link Library 动态链接库
SO: Shared Object 共享对象
动态库的特点:
- 程序运行的时候才会使用到动态库中的内容
- 在链接的时候把动态库的**“访问方式”**放到可执行文件中
- 使用动态库而生成的可执行文件必须依赖到动态库才能成功的运行程序
- 使用动态库的可执行文件体积相对于使用静态库的小
1.3 静态库和动态库的简单区别
从静态库和动态库的特点就可以看得的是,静态库的优点就是动态库的缺点,动态库的优点就是静态库的缺点。
二、静态库和动态库的创建
- 使用命令行创建静态库和动态库
关于静态库和动态库的创建要注意的事项:
- 操作系统不同,静态库和动态库的内部格式不同
- 同操作系统,不同编译器,静态库和动态库的生成方式也不同
- 同操作系统,不同编译器,静态库和动态库的使用方式也不同
- 静态库和动态库的创建和使用一定是基于指定的操作系统和编译器才可以
2.1 基于Widows,MinGW的静态库的创建
头文件:myMath.h
#ifndef _myMath_H_
#define _myMath_H_
typedef struct MyMath
{
int a;
int b;
}myMath;
MyMath* creatMathObject(int a,int b);
int add(MyMath* mobj);
int sub(MyMath* mobj);
void delMathObject(MyMath* mobj);
#endif
源文件:myMath.c
#include "myMath.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
MyMath* creatMathObject(int a,int b)
{
MyMath* mobj=(MyMath*)malloc(sizeof(MyMath));
assert(mobj);
mobj->a=a;
mobj->b=b;
return mobj;
}
int add(MyMath* mobj)
{
return mobj->a+mobj->b;
}
int sub(MyMath* mobj)
{
return mobj->a-mobj->b;
}
void delMathObject(MyMath* mobj)
{
if(mobj==NULL)
return ;
free(mobj);
mobj=NULL;
}
进入终端
gcc -c myMath.c -o myMath.o -static
# 生成静态库要加-static选项,位置在不脱离现实的情况下随便放
ar -crus libmymath1.lib myMath.o
# 生成静态库文件,方式一
ar -crus libmymath2.a myMath.o
# 生成静态库文件,方式二
# c create
# r replace
# u update
# s search
2.2 基于Widows,MinGW的动态库的创建
头文件和源文件还是上面的
进入终端:
gcc -c myMath.c -o myMath.o -fpic
# 先生成.o文件,-fpic选加
gcc myMath.o -o libmymath3.dll -shared
# 生成动态库文件
#也可以将两个命令结合在一起
gcc -c myMath.c -o libmymath3.dll -fpic -shared
# -shared是生成动态库的关键选项,在不脱离现实的情况下位置无关
# -fpic是选加的
# f file
# p position
# i independent
# c code
三、静态库和动态库的使用
3.1 静态库的使用
使用之前的条件:
- 拿到.h文件
- 拿到静态库文件
3.1.1 单目录
和本地的项目源文件放在以下,操作起来很简单。
直接把头文件包含过来
//main.c
#include <stdio.h>
#include "myMath.h" //没有源文件,源文件已经被编译成静态库文件了
int main()
{
MyMath* mobj=creatMathObject(7,5);
int result=add(mobj);
printf("%d\n",result);
result=sub(mobj);
printf("%d\n",result);
delMathObject(mobj);
printf("over\n");
return 0;
}
进入终端:
# 正常编译操作生成main.o
gcc -c main.c -o main.o
# 链接的时候需要把静态库也链接过来
gcc main.o -L. -llibmymath1 -o main.exe # .lib
# gcc main.o -L. -lmymath1 -o main.exe # 会报错
gcc main.o -L. -lmymath2 -o main2.exe # .a
3.1.2 多目录
目录结构
.
|--bin
|--include
|--myMath.h
|--lib
|--libmymath1.lib
|--libmymath2.a
|--obj
|--src
|--main.c # main.c文件还是上面的
进入终端:
# 正常编译操作生成main.o
gcc -c src/main.c -o obj/main.o -I include
# 链接的时候需要把静态库也链接过来
gcc main.o -L./lib -llibmymath1 -o bin/main.exe # .lib
gcc main.o -L./lib -lmymath2 -o bin/main2.exe # .a
3.2 动态库的使用
基于Windows下使用动态库
使用条件:
- 拿到.h文件
- 拿到动态库文件
3.2.1 单目录
还是上面的main.c文件
进入终端:
# 正常编译操作生成main.o
gcc -c main.c -o main.o
# 链接的时候需要把动态库也链接过来
gcc main.o -L. -llibmymath3 -o main.exe # .lib
./main.exe # 成功运行
3.2.2 多目录
目录结构:
.
|--bin
|--libmymath3.dll
|--include
|--myMath.h
|--obj
|--src
|--main.c # main.c文件还是上面的
进入终端:
# 正常编译操作生成main.o
gcc -c src/main.c -o obj/main.o -I include
# 链接的时候需要把动态库也链接过来
gcc main.o -L./bin -llibmymath3 -o bin/main.exe # .lib
cd bin
./main.exe #正常运行
四、Makefile写法
单文件就不写Makefile了,太简单了直接使用gcc命令比较简单也比快捷
4.1 使用静态库时Makefile写法
BIN=./bin
OBJ=./obj
INC=./include
SRC=./src
LIB=./lib
SRCS=$(wildcard $(SRC)/*.c)
OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
TARGET=main
TARGET_PATH=$(BIN)/$(TARGET)
CC=gcc
CFLAGS=-g -Wall -I$(INC)
LIB_PATH=-L $(LIB)
LIB_FLAGS=-l libzzz
$(TARGET_PATH):$(OBJS)
$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
$(OBJ)/%.o:$(SRC)/%.c
$(CC) -c $(CFLAGS) $^ -o $@
.PHONY: clean
clean:
del /Q /F obj
4.2 使用动态库时Makefile写法
BIN=./bin
OBJ=./obj
INC=./include
SRC=./src
SRCS=$(wildcard $(SRC)/*.c)
OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
TARGET=main
TARGET_PATH=$(BIN)/$(TARGET)
CC=gcc
CFLAGS=-g -Wall -I$(INC)
LIB_PATH=-L$(BIN)
LIB_FLAGS=-lmymath
$(TARGET_PATH):$(OBJS)
$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
$(OBJ)/%.o:$(SRC)/%.c
$(CC) -c $(CFLAGS) $^ -o $@
.PHONY: clean
clean:
del /Q /F obj
4.3 使用静态库和动态库时Makefile写法
BIN=./bin
OBJ=./obj
INC=./include
SRC=./src
LIB=./lib
SRCS=$(wildcard $(SRC)/*.c)
OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
TARGET=main
TARGET_PATH=$(BIN)/$(TARGET)
CC=gcc
CFLAGS=-g -Wall -I$(INC)
LIB_PATH=-L$(BIN) -L$(LIB)
LIB_FLAGS=-lmathdm -llibmathas
$(TARGET_PATH):$(OBJS)
$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
$(OBJ)/%.o:$(SRC)/%.c
$(CC) -c $(CFLAGS) $^ -o $@
.PHONY: clean
clean:
del /Q /F obj
搭配视频看会更好哟!!!
C/C++静态库和动态库基于Windows和VScode