欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++动态库的创建和使用实战

程序员文章站 2022-06-03 21:55:24
...

一 点睛

动态库又称为共享库。这类库的名字一般是libxxx.M.N.so,xxx为库的名字,M为库的主版本号,N为库的副版本号。当然也可以不用版本号,但名字必须要有,即libxxx.so。

和静态库比较,动态库并没有在编译的时候被编译进目标代码中,程序在执行相关函数时才调用该函数库里相应函数,因此使用动态库的可执行文件比较小。由于函数库没有被整合进可执行文件,而是程序运行时候动态申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响可执行文件,所以动态函数库升级比较方便。

Linux系统有几个重要的目录存放相应的函数库,如/lib  /usr/lib

编译链接动态库时,动态库会在可执行文件内留下一个标记,指明当程序执行时,首先必须载入这个库。

由于动态库节省空间,Linux进行链接的默认操作是首先链接动态库,也就是说,如果同时存在静态库和动态库,不特别指定的话,将与动态库相链接。

动态库文件的后缀是.so,可以直接使用gcc或g++生成。

二 实战——创建和使用动态库

1 编写源文件test.cpp

#include  <stdio.h>
#include <iostream>
using namespace std;
void f(int age)
{
    cout << "your age is " << age << endl;
    printf("age:%d\n", age);
}

2 生成动态库文件libtest.so

[[email protected] test]# g++ test.cpp -fPIC -shared -o libtest.so

3 编写main.cpp

extern void f(int age);   //声明要使用的函数
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    f(66);
    cout << "HI" << endl;
    
    return 0;
}

4 编译运行

[[email protected] test]# g++ main.cpp -o main -L ./ -ltest
[[email protected] test]# ll
total 32
-rwxr-xr-x. 1 root root 8720 Apr 14 10:41 libtest.so
-rwxr-xr-x. 1 root root 9168 Apr 14 10:44 main
-rw-r--r--. 1 root root  179 Mar 24 13:11 main.cpp
-rw-r--r--. 1 root root  155 Mar 24 13:11 test.cpp
[[email protected] test]# ./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

5 说明

-L:用来告诉g++去哪里找库文件,它后面的空格和./表示在当前目录下寻找库,或者直接写-L.

-l:用来指定具体的库,其中lib和.a不用显示写出,g++和gcc会自动去寻找libtest.so

默认情况下,g++或gcc会首先搜索动态库(.so)文件,找不到后再去寻找静态库(.a)文件。当前目录下以test命名的库文件有动态库文件(libtest.so),因此g++可以找到。

这里编译链接成功了,但发现运行出错,原因是:虽然库文件和main文件在同一目录下,但程序main并不知道。这里有三种解决方法。

第一种:将库复制到/usr/lib或/lib下,然后执行ldconfig命令

[[email protected] test]# cp libtest.so /lib
[[email protected] test]# ldconfig
[[email protected] test]# ./main
your age is 66
age:66
HI

第二种:在命令前加环境变量

[[email protected] test]# LD_LIBRARY_PATH=/root/C++/ch10/10.3/test/ ./main
your age is 66
age:66
HI

这种方法虽然简单,但环境变量只对当前命令有效,当该命令执行完后,该环境变量就无效了。此法是暂时之法。

第三种:修改/etc/ld.so.conf文件,将路径添加,然后执行ldconfig命令

[[email protected] test]# vi /etc/ld.so.conf
[[email protected] test]# ldconfig
[[email protected] test]# ./main
your age is 66
age:66
HI
[[email protected] test]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/root/C++/ch10/10.3/test/

ldconfig命令作用:主要是在默认搜索目录(/lib和/usr/lib)以及动态配置文件/etc/ld.so/conf内列的目录下,搜索出可共享的动态库,进而创建出装入程序(ld.so程序)所需连接和缓存文件。缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。

可以在/etc/ld.so.cache文件中搜索到/root/C++/ch10/10.3/test/libtest.so

 

相关标签: C++ 动态库