c语言中静态库动态库的创建与使用

在c程序中存在两种库文件,分别为静态库文件与动态库文件也叫共享库文件,系统的库文件存放路径为 usr/lib目录下:
静态库文件就是一些.o目标文件的集合,以.a结尾。
静态库在程序链接的时候使用,连接器会将程序中使用到的函数的代码从库文件拷贝到可执行文件中,一旦链接完成,
在程序执行的时候就不需要静态库了。
静态库的创建:

首先看一下源文件

fun.c
#include <stdio.h>
int foo(char* ch)
{
	printf("foo: %s\n",ch);
	return 0;
}

fun.h
#ifndef _FUNC_
#define _FUNC_
#ifdef __cplusplus
extern "C" {  //告诉c++编译此处使用gcc编译
#endif
int foo(char* ch);
#ifdef __cplusplus
}
#endif
#endif

main.cpp
#include "fun.h"
#include <stdio.h>
#include <iostream>
using namespace::std;
int main()
{
	char* ch = "我是字符串";
	foo(ch);
	cout << "lalalala" << endl;
	return 0;
}
若需要直接使用make编译生成可执行文件,则附上makefile文件:
CC = gcc
CXX = g++
ADD_CFLAGS := -Wall -g

CFLAGS := $(ADD_CFLAGS) $(CFLAGS)
CPPFLAGS := $(ADD_CFLAGS)
LDFLAGS := $(LDFLAGS)

targets = test
.PHONY: all
all: $(targets)
test: main.o fun.o
	$(CXX) $^ -o $@ $(LDFLAGS)
main.o: main.cpp
	$(CXX) $(CPPFLAGS) -c $< -o $@
fun.o: fun.c fun.h
	$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
	$(RM) $(targets) *.o
当前目录下执行make即可编译。

接下来看一下如何将fun.c编译成库文件:

现在要将fun.c编译成静态库,libmytest.a

1.将fun.c 和main.c 编译成目标文件,生成fun.o main.o
    gcc -o fun.o -c fun.c 
    g++ -o mian.o -c main.cpp

2.将fun.o编译成静态库文件,libmytest.a
    编译命令为: ar rcs lib库文件.a 目标文件1 目标文件2 ...
    此处使用 ar rcs libmytest.a fun.o
    r:表示将.o的目标文件加入到静态库中
  c:表示创建静态库
  s:表示生产索引
注意:生成库文件时建议在名字前加上前缀lib,及lib库文件名.a,否则后面链接时会出错。

接下来要使用静态库:
编译方式有两种:
    g++ -o 可执行文件 调用者的目标文件(就是这里的fun.o和main.o) -Ldir -l库文件名(不加lib)
    g++ -o 可执行文件 头文件路径 调用者的源文件(就是这里的main.c文件) -Ldir -l库文件名(不加lib)

现在开始编译,生成可执行文件test:
    g++ -o test main.o -L./ -lmytest
-Ldir 指的是静态库的链接路径,由于我的就是在当前目录下,直接写./就可以了

运行./test
user@sursoft-desktop:~$ ./test
foo: 我是字符串
lalalala

当将静态库libmytest.a删除后再次运行,依然可正常运行。

动态库的创建与使用:
动态库是指在程序链接的时候并不像静态库那样拷贝使用函数中的代码,而只是做一些标记,在程序开始启动(实际上在加载程序时)运行的时候,
加载所需的函数。

动态库的创建:
源文件还是fun.c fun.h main.c

第一步:首先还是先生成fun.o main.o目标文件
第二步:使用gcc编译
    gcc -shared -fPIC -o lib库文件.so 目标文件1 目标文件2 ...
编译生成libmytest.so:
    gcc -shared -fPIC -o libmytest.so fun.o
若编译出错:/usr/bin/ld: fun.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
      fun.o: could not read symbols: Bad value collect2: ld returned 1 exit status
此原因是系统造成的,需要重新生成一下目标文件,编译命令如下:
gcc -o fun.o -c -fPIC fun.c
然后再执行gcc -shared -fPIC -o libmytest.so fun.o即可;

动态库的使用(和静态库一样):
    g++ -o 可执行文件 调用者的目标文件(就是这里的fun.o和main.o) -Ldir -l库文件名(不加lib)
    g++ -o 可执行文件 头文件路径 调用者的源文件(就是这里的main.c文件) -Ldir -l库文件名(不加lib)

现在开始编译,生成可执行文件test:
    g++ -o test main.o -L./ -lmytest

运行./test
结果出错:libmytest.so: cannot open shared object file: No such file or directory
需要手动配置一下路径:
    第一种:cp libmytest.so /usr/lib
    第二种:export LD_LIBRARY_PATH=./
然后再次运行,OK

若删除libmytest.so,运行./test将会出错。


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值