栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux系统下gcc生成静态库和动态库及实例

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux系统下gcc生成静态库和动态库及实例

本文目录
  • 一、前言
  • 二、用gcc生成静态库和动态库
    • (一).hello实例
      • 1.准备过程
      • 2.静态库的使用
      • 3.动态库的使用
    • (二).linux下静态库.a和.so库文件的生成和使用实例
      • 1.准备过程
      • 2.静态库.a文件的生成与使用
      • 3.动态库.so文件的生成与使用
    • (三).其他实例
      • 1.准备过程
      • 2.静态库使用
      • 3.动态库的使用
      • 4.静态库与动态库的生成文件大小的比较
  • 三、参考资料

一、前言

我们通常把一些公用函数制作成函数库,供其他程序使用,函数库分为静态库和动态库两种。
静态库在程序编译时会连接到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。
本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。

二、用gcc生成静态库和动态库 (一).hello实例 1.准备过程

(1) .创建一个作业目录,保存本次练习的文件

#mkdir test1
#cd test1

(2) .程序代码
hello.h为该函数库的头文件

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name)
#endif //HELLO_H

hello1.c是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出“Hello,XXX!"。

#include 
void hello(const char *name)
{
printf("Hello %s!n",name);
}

main.c为测试库文件的主程序,在主程序中调用了公用函数hello

#include "hello.h"
int main()
{
hello("everyone");
return 0;
}

(3) .将hello.c编译成.o文件
在系统提示符下键入以下命令得到hello.o文件

gcc -c hello.c

运行ls命令看看是否生成了hello.o文件

ls


看到有hello.o文件,说明本部操作完成。

2.静态库的使用

(1) .由.o文件创建静态库
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名.a。

ar -crv libmyhello.a hello.o

运行ls命令看看是否生成了静态库文件文件

ls


看到libmyhello.a文件,说明本部操作完成。

(2) .在程序中使用静态库
静态库制作完了,如何使用它内部的函数呢?只需要在使用到这些公用函数的源程序中包 含这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明静态库名,gcc 将会从 静态库中将公用函数连接到目标文件中。注意,gcc 会在静态库名前加上前缀 lib,然后追 加扩展名.a 得到的静态库文件名来查找静态库文件。 在程序 main.c 中,我们包含了静态库的头文件 hello.h,然后在主程序 main 中直接调用 公用函数 hello。下面先生成目标程序 hello,然后运行 hello 程序看看结果如何。

方法一:

 gcc -o hello main.c -L. –lmyhello 

自定义的库时,main.c 还可放在-L.和 –lmyhello 之间,但是不能放在它俩之后,否则会提 示 myhello 没定义,但是是系统的库时,如 g++ -o main(-L/usr/lib) -lpthread main.cpp 就不出错。

方法二:

gcc main.c libmyhello.a -o hello

方法三:
先生成 main.o:

gcc -c main.c 

再生成可执行文件:

gcc -o hello main.o libmyhello.a

动态库连接时也可以这样做。

输入./hello

说明操作成功了。
然后我们删除静态库文件试试公用函数hello是否真的连接到目标文件hello中了

rm libmyhello.a
./hello


可以看到libmyhello.a已经被删除,而程序照常运行,说明静态库中的公用函数已经连接到目标文件中。

3.动态库的使用

(1) .由.o文件创建动态库文件
动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其 文件扩展名为.so。例如:我们将创建的动态库名为 myhello,则动态库文件名就是 libmyh ello.so。用 gcc 来创建动态库。
在系统提示符下键入以下命令得到动态库文件 libmyhello.so。

gcc -shared -fPIC -o libmyhello.so hello.o

提示错误

这是因为在创建hello.o文件时没有键入-fPIC使不一致导致的
重新输入

gcc -o -fPIC hello.c

之后再输入

gcc -shared -fPIC -o libmyhello.so hello.o

用ls命令查看,发现动态库已经创建成功

(2) .在程序中使用动态库
在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含 这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明动态库名进行编译。程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提 示类似上述错误而终止程序运行。我们将文件 libmyhello.so 复制到目录/usr/lib 中在运行,否则会报错。

gcc -o hello main.c -L. -lmyhello

之后输入./hello看程序是否执行

./hello


果然出现了错误。
解决方法是将文件 libmyhello.so 复制到目录/usr/lib 中在运行
输入mv libmyhello.so 提示权限不够

所以我们需要临时权限提高
输入sudo mv libmyhello.so就可以解决
之后输入./hello,程序成功运行,如下图所示

(二).linux下静态库.a和.so库文件的生成和使用实例 1.准备过程

(1) .先创建一个作业目录,保存本次示例文件

mkdir test2
cd test2

(2) .实例代码

A1.c:

#include  
void print1(int arg)
{
 printf("A1 print arg:%dn",arg); 
}

A2.c:

#include 
 void print2(char *arg)
 { 
 printf("A2 printf arg:%sn", arg);
  }

A.h:

#ifndef A_H 
#define A_H 
void print1(int);
void print2(char *);
#endif

test.c:

#include 
#include "A.h" 
int main()
{
 print1(1); 
 print2("test"); 
 exit(0); 
}
2.静态库.a文件的生成与使用
gcc -c A1.c A2.c
ar crv libafile.a A1.o A2.o

使用.a 库文件,创建可执行程序(若采用此种方式,需保证生成的.a 文件与.c 文件保 存在同一目录下,即都在当前目录下)
如图都在libafile文件夹内

gcc -o test test.c libafile.a
./test

如图所示,说明使用成功

3.动态库.so文件的生成与使用

生成目标文件(xxx.o() 此处生成.o 文件必须添加"-fpic"(小模式,代码少),否则在生成.so 文件时会出错)
gcc -c -fpic A1.c A2.c
生成共享库.so 文件
gcc -shared *.o -o libsofile.so
使用.so 库文件,创建可执行程序
gcc -o test test.c libsofile.so
./test
发现出现错误:
./test: error while loading shared libraries: libsofile.so: cannot open shared object file: No such file or directory
运行 ldd test,查看链接情况

  ldd test 
  linux-vdso.so.1 => (0x00007fff0fd95000) 
  libsofile.so => not found 
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f937b5de000) 
  /lib64/ld-linux-x86-64.so.2 (0x0000563f7028c000)

发现确实是找不到对应的.so 文件。 这是由于 linux 自身系统设定的相应的设置的原因,即其只在/lib and /usr/lib 下搜索对应 的.so 文件,故需将对应 so 文件拷贝到对应路径。

sudo cp libsofile.so /usr/lib 

再次执行./test,即可成功运行。
全过程如图所示

(三).其他实例 1.准备过程

(1) .创建一个作业目录,保存本次练习的文件

#mkdir example1
#cd example1

(2) .实例代码

sub1.c:

float x2x(int a,int b)
{
	float c=0;
	c=a+b;
	return c;
}

sub2.c:

float x2y(int a,int b)
{
	float c=0;
	c=a/b;
	return c;
}

sub.h:

#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

main.c:

#include
#include"sub.h"
void main()
{
	int a,b;
	printf("Please input the value of a:");
	scanf("%d",&a);
	printf("Please input the value of b:");
	scanf("%d",&b);
	printf("a+b=%.2fn",x2x(a,b));
	printf("a/b=%.2fn",x2y(a,b));
}
2.静态库使用
gcc -c sub1.c sub2.c

ar crv libsub.a sub1.o sub2.o

gcc -o main main.c libsub.a


可以看到输入./main,按要求输入a,b,可以看到输出是正确的,说明程序正确执行。

3.动态库的使用
gcc -shared -fPIC -o libsub.so sub1.o sub2.o
gcc -o main main.c libsub.so
sudo mv libsub.so /usr/lib


可以看到输入./main,按要求输入a,b,可以看到输出是正确的,说明程序正确执行。

4.静态库与动态库的生成文件大小的比较

静态库

动态库

可以看到态库要比动态库要小很多,生成的可执行文件大小也存在较小的差别。

三、参考资料

gcc生成静态库.a和动态库.so.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/296698.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号