C语言程序在开发过程中通常会使用遇到动态库或者是静态库函数的创建和使用,这里做简要的记录。
A.静态库函数的创建
1.源文件getSum.c
#include "getSum.h"
int getSum( int a, int b )
{
return a + b;
}
2.头文件getSum.h
#ifndef __STATIC_H__
#define __STATIC_H__
#include <stdio.h>
extern int getSum( int a, int b );
#endif //__STATIC_H__
说明:extern关键字说明函数的定义来自其他源文件,这里可以省去(注:只在头文件做申明不定义)
3. 静态库文件编译Makefile
###########################################
#
# NAME: Makefile for creating static libs
# AUTHOR: HAMMING
# TIME: 2017-10-26
# VERSION: V1.0
# MODIFY:
#
##########################################
# 1、准备工作,编译方式、目标文件名、依赖库路径的定义。
CC = gcc
CFLAGS := -Wall -O3
# 头文件和lib(动态库或静态库)路径
INC_CANGHAI = /home/canhai/libUsage/lib
LIB_CANGHAI = /home/canhai/libUsage/lib
SRCS := $(wildcard *.c)
OBJS := $(patsubst %.c, %.o, $(SRCS)) #.o文件与.c文件同名
LIB = libmath2.a # 目标文件名
OPENCV_INC= -I $(INC_CANGHAI) # 指定使用到的头文件所在路径
INCLUDE_PATH = $(OPENCV_INC)
LIB_PATH = -L $(LIB_CANGHAI) # 指定链接库所在路径,编译过程中要使用到的库还是要以-lmath形式写出来
# 依赖的lib名称
OPENCV_LIB =
all : $(LIB)
# 2. 生成.o文件
%.o : %.c # 这里也可以写成.c.o的形式
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDE_PATH) $(LIB_PATH) $(OPENCV_LIB)
# 3. 生成静态库文件
$(LIB) : $(OBJS)
rm -f $@
ar -r $@ $(OBJS)
rm -f $(OBJS)
tags :
ctags -R *
# 4. 删除中间过程生成的文件
clean:
rm -f $(OBJS) $(TARGET) $(LIB)
# 指定使用到的头文件所在路径
INCLUDE_PATH = $(OPENCV_INC)
LIB_PATH = -L $(LIB_CANGHAI) # 指定链接库所在路径,编译过程中要使用到的库还是要以-lmath形式写出来
# 依赖的lib名称
OPENCV_LIB =
all : $(LIB)
# 2. 生成.o文件
%.o : %.c # 这里也可以写成.c.o的形式
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDE_PATH) $(LIB_PATH) $(OPENCV_LIB)
# 3. 生成静态库文件
$(LIB) : $(OBJS)
rm -f $@
ar -r $@ $(OBJS)
rm -f $(OBJS)
tags :
ctags -R *
# 4. 删除中间过程生成的文件
clean:
rm -f $(OBJS) $(TARGET) $(LIB)
B.动态库函数的创建
1.源文件getReduce.c
#include "getReduce.h"
int getReduce( int a, int b )
{
return a - b;
}
2.头文件的创建getReduce.h
#ifndef __DYNAMIC_H__
#define __DYNAMIC_H__
#include <stdio.h>
extern int getReduce( int a, int b);
#endif //__DYNAMIC_H__
3.动态库文件编译的Makefile
###########################################
#
# NAME: Makefile for creating static libs
# AUTHOR: HAMMING
# TIME: 2017-10-26
# VERSION: V1.0
# MODIFY:
#
##########################################
# 1、准备工作,编译方式、目标文件名、依赖库路径的定义。
CC = gcc
CFLAGS := -Wall -O3
# opencv 头文件和lib路径
INC_CANGHAI = /home/canhai/libUsage/lib
LIB_CANGHAI = /home/canhai/libUsage/lib
SRCS := $(wildcard *.c)
OBJS := $(patsubst %.c, %.o, $(SRCS)) #.o文件与.c文件同名
LIB = libmath1.so # 目标文件名
OPENCV_INC= -I $(INC_CANGHAI)
INCLUDE_PATH = $(OPENCV_INC)
LIB_PATH = -L $(LIB_CANGHAI)
# 依赖的lib名称
OPENCV_LIB =
all : $(LIB)
# 2. 生成.o文件
%.o : %.c
$(CC) $(CFLAGS) -fpic -c $< -o $@ $(INCLUDE_PATH) $(LIB_PATH) $(OPENCV_LIB)
# 3. 生成动态库文件
$(LIB) : $(OBJS)
rm -f $@
$(CC) -shared -o $@ $(OBJS)
rm -f $(OBJS)
tags :
ctags -R *
# 4. 删除中间过程生成的文件
clean:
rm -f $(OBJS) $(TARGET) $(LIB)
C.动态库和静态库函数的调用
1.头文件(这里可以通过编译的时候指定头文件所在路径 -I $(PATH))
2.源文件main.c
#include "getSum.h"
#include "getReduce.h"
int main( int argc, char *argv[])
{
int a = 0;
int b = 0;
int c = 0;
c = getSum( a, b );
printf( "%d + %d = %d\n", a, b, c );
c = getReduce( a, b );
printf( "%d - %d = %d\n", a, b, c );
return 0;
}
3.编译源程序使用的Makefile
###########################################
#
# NAME: Makefile for Hello.cc
# AUTHOR: HAMMING
# TIME: 2017-10-26
# VERSION: V1.0
# MODIFY:
#
##########################################
GCC = gcc
CFLAGS = -g -Wall
INCLUDE:=/home/canhai/libUsage/lib
LIBS = $(wildcard /home/canhai/libUsage/lib/*.a)
SRCS := $(wildcard *.c)
TARGET := $(patsubst %.c, %, $(SRCS))
OBJDIR = .
.cc:
$(CC) $(C_FLAGS) -o $@ $< -I $(INCLUDE) -lmath1 -lmath2 -L ../lib
all: $(TARGET) clean
clean:
rm -rf *.o
D. 注意事项:
1、在测试过程中,经常会报错:找不到.so文件,或是头文件所在目录。一种简单的解决方法如下:
在linux终端输入如下命令:(永久有效需要配置到环境变量中)
Makefile中还要注意$@ $< 的顺序问题
只有动态库才需要在编译的时候进行链接-L $(PATH) -lmath2,静态库不需要
export LD_LIBRARY_PATH=~/libUsage/lib:LD_LIBRARY_PATH:
<span style="color:#111111">export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/libUsage/lib:</span>
E.参考资料