您的位置:首页 > 编程语言 > C语言/C++

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

2017-06-29 15:07 281 查看
在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将会出错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: