C++动态库的创建和使用实战
一 点睛
动态库又称为共享库。这类库的名字一般是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
上一篇: Javascript匿名函数
下一篇: 从何入手写一个自带界面的Shell程序