Linux
下创建与使用动态库
linux
动态库的命名规则
动态链接库的名字形式为
libxxx.so
,前缀是
lib
,后缀名为“
.so
”。
l
针对于实际库文件,每个共享库都有个特殊的名字“
soname
”。在程序启动后,程序通过这个名字来告诉动态加载器该载入哪个共享库。
l
在文件系统中,
soname
仅是一个链接到实际动态库的链接。对于动态库而言,每个库实际上都有另一个名字给编译器来用。它是一个指向实际库镜像文件的链接文件(
lib+soname+.so
)。
创建动态库(
.so
)
编写四则运算动态库代码:
|
|
l
首先,生成目标文件,此时要加编译器选项
-fpic
|
-fPIC
创建与地址无关的编译程序(
pic
,
position independent code
),是为了能够在多个应用程序间共享。
l
然后,生成动态库
,此时要加链接器选项
-shared
|
-shared
指定生成动态链接库。
其实上面两个步骤可以合并为一个命令:
|
使用动态库
编写使用动态库的测试代码:
|
|
引用动态库编译成可执行文件(跟静态库方式一样):
|
然后运行:
./a.out
,发现竟然报错了!!!
可能大家会猜测,是因为动态库跟测试程序不是一个目录,那我们验证下是否如此:
发现还是报错!!!那么,在执行的时候是如何定位共享库文件的呢?
1)
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器
(dynamic linker/loader)
。
2)
对于
elf
格式的可执行程序,是由
ld-linux.so*
来完成的,它先后搜索
elf
文件的
DT_RPATH
段—环境变量
LD_LIBRARY_PATH
—
/etc/ld.so.cache
文件列表—
/lib/,/usr/lib
目录找到库文件后将其载入内存。
如何让系统能够找到它:
l
如果安装在
/lib
或者
/usr/lib
下,那么
ld
默认能够找到,无需其他操作。
l
如果安装在其他目录,需要将其添加到
/etc/ld.so.cache
文件中,步骤如下:
n
编辑
/etc/ld.so.conf
文件,加入库文件所在目录的路径
n
运行
ldconfig
,该命令会重建
/etc/ld.so.cache
文件
我们将创建的动态库复制到
/usr/lib
下面,然后运行测试程序。
在
Linux
下显式调用动态库
#include
,提供了下面几个接口:
l
void *
dlopen
( const char * pathname, int mode )
:函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。
l
void*
dlsym
(void* handle,const char* symbol)
:
dlsym
根据动态链接库操作句柄
(pHandle)
与符号
(symbol)
,返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
l
int
dlclose
(void *handle)
:
dlclose
用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为
0
时
,
才会真正被系统卸载。
l
const char *dlerror(void)
:当动态链接库操作函数执行失败时,
dlerror
可以返回出错信息,返回值为
NULL
时表示操作函数执行成功。
本文转自:
http://www.cnblogs.com/skynet/p/3372855.html