精华内容
下载资源
问答
  • nbsplinux/Unix相关Linux动态链接库创建和使用浅谈.pdf6页本文档一共被下载:次,您可全文免费在线阅读后下载本文档。 下载提示1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔...

    您所在位置:网站首页 > 海量文档

    &nbsp>&nbsp计算机&nbsp>&nbsplinux/Unix相关

    a476e75ce57e4882405abe7b4456fc6b.gif

    Linux下动态链接库的创建和使用浅谈.pdf6页

    本文档一共被下载:2377011b61454b208b34ad77b4c31088.gif次,您可全文免费在线阅读后下载本文档。

    072ad097814a33d1ad18e33ca14a5a9e.png

    9ec2792a743ebdf4575ee09a03c275ea.png

    7af312d1be2cfc1e59f15880bb7a7e7a.png

    5f207613e329ca76dc87c76d3ff77e64.png

    adf7aa3071c520b8a2063089f549261c.png

    下载提示

    1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。

    2.该文档所得收入(下载+内容+预览三)归上传者、原创者。

    3.登录后可充值,立即自动返金币,充值渠道很便利

    Linux 下动态链接库的创建和使用浅谈

    李兴飞 2011-9-6

    一直以来,我对Linux 下的动态链接库的理解比较模糊,由于要在工程中需要使用动态

    链接库,所以这几天对这块进行了扫盲。我在学习Linux 环境下的动态使用时,是带着下面

    三个问题进行的:

    (1) 什么是动态链接库,作用是什么?

    (2 ) 使用c 编写动态库,c 程序如何调用动态库?

    (3 ) 使用c++编写动态库,c 程序如何调用动态库?

    (4 ) 是否可以将c 和c++分别别写的代码一个整合到动态库中?

    一、什么是动态链接库?作用是什么?

    动态链接库是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的

    例程和资源。动态链接库的扩展名是.so。

    作用:使用动态链接库可以有效的利用空间和资源,使应用程序可以共享相同功能的代

    码模块。

    二、使用c 编写动态库,c 程序如何调用动态库?

    下面采用例子介绍:

    (1)首先编写动态链接库的对外暴露 API 的头文件test_c.h ,我们这里定义的API 是

    test_c_api() 函数,代码如下:

    >>>>>>>>>>>>>>>>>>>>>>

    test_c.h

    >>>>>>>>>>>>>>>>>>>>>>

    #ifndef __TEST_C_H

    #define __TEST_C_H

    #include

    void test_c_api();

    #endif

    动态链接库的实现部分,下边是一个打印hello word 的源代码:

    >>>>>>>>>>>>>>>>>>>>>>

    test_c.c

    >>>>>>>>>>>>>>>>>>>>>>

    #include "test_c.h"

    void test_c_api()

    {

    printf("test_c hello word!\n");

    }

    (2 )编译生成动态链接库:gcc –c –fPIC test_c.c 产生test_c.o 目标文件

    gcc –shared –o libtest.so test_c.o 生成动态链接库libtest.so

    注意:-fPIC 选项的意思是产生于本地无关的代码

    -shared 选项生产动态链接库

    也可以直接使用gcc –fPIC –shared –o libtest.so test_c.c 生成动态链接库。

    (3 )测试动态链接库

    测试代码:

    >>>>>>>>>>>>>>>>>>>>>>>>

    test.c

    >>>>>>>>>>>>>>>>>>>>>>>>

    #include "test_c.h"// 包含动态链接库的头文件,其中定义了动态链接库暴露的所有API

    int main()

    {

    test_c_api();//c 编写的动态链接库的API

    return 0;

    }

    编译测试文件 gcc –o test test.c –I . –L . –ltest 生成可执行文件test

    ./test

    注意: –I 头文件目录 –L 链接库的目录

    使用C 程序调用C 编写的动态库是非常简单的。接下来我们看一下使用C 程序调用C++编写

    的动态库。由于编译后的C++和C 函数命名规则的不同,导致C 不能直接调用C++编写的动

    态链接库。在调用之前必须进行一些处理 (如:extern "C" )。

    三、使用c++编写动态库,c 程序如何调用动态库?

    同样使用例子介绍C 程序调用C++编写的动态链接库

    (1)首先编写C++动态库的对C 开放API 的头文件test_cpp.h

    >>>>>>>>>>>>>>>>>>>>>>>

    test_cpp.h

    >>>>>>>>>>>>>>>>>>>>>>>

    #ifndef __TEST_CPP_H

    #define __TEST_CPP_H

    #ifdef __cplusplus

    extern "C"{

    #endif

    void test_

    发表评论

    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。

    用户名:

    验证码:

    c9f2bced460b0329ba0aadbbc3f0fc71.png

    匿名?

    发表评论

    展开全文
  • LINUX动态链接库高级应用在《LINUX动态链接库创建与应用》一文中,我介绍了LINUX动态链接库的基本知识.其要点是:用户根据实际情况需要,利用dlopen,dlsym,dlclose等动态链接库操作函数,装入指定的动态链接库中指定...

    LINUX动态链接库高级应用

    在《LINUX下动态链接库的创建与应用》一文中,我介绍了LINUX动态链接库的基本知识.其要点是:用户根据实际情况需要,利用dlopen,dlsym,dlclose等动态链接库操作函数,装入指定的动态链接库中指定的函数,然后加以执行.程序中使用很少的动态函数时,这样的做法尚可.如果程序需要调用大量的动态函数,那么采用这样的编程手段将是非常繁复的,所以我们必须使用一种更为聪明的办法,以减少代码量,提高工作效率.这就是现在我要举例介绍的《LINUX动态链接库高级应用》.

    注:本文举的例子类似上篇文章,只是文件的内容已做相应修改,裁减了不少.示例程序ady.c和两个动态函数的源程序getdate.c与gettime.c仅修改了头文件的名字,其内容不再列出.本文使用头文件为adatetime.h.

    要想高效地应用LINUX动态链接库(尤其是用户自己编写的),需要做以下工作:

    一、编写合格的动态链接库头文件

    C语言的头文件,可供一个或多个程序引用,里面一般定义程序所需的常量,自定义类型及函数原型说明等.其中的函数原型说明,则供编译器检查语法,用于排除引用参数时类型不一致的错误.只有编写合格的动态链接库头文件,程序员才能正确使用动态链接库内的函数.

    动态链接库头文件要采用C语言标准格式,其中的动态函数原型定义,不必象上文介绍的那样用(*动态函数名)的描述形式.请看下面的例子:(每行开始的数字为所在行行号,为笔者添加,供注解使用)

    1 /* adatetime.h

    : 纵横软件制作中心雨亦奇(zhsoft@371.net)编写, 2002-03-06. */

    2

    3 #ifndef

    __DATETIME_H

    4

    5 #define

    __DATETIME_H

    6

    7 /* 日期结构 */

    8 typedef struct

    9 {

    10 int year;

    11 int mon;

    12 int day;

    13 }DATETYPE;

    14

    15 /* 时间结构 */

    16 typedef struct

    17 {

    18 char hour;

    19 char min;

    20 char sec;

    21 }TIMETYPE;

    22

    23 int

    getdate(DATETYPE *d); /* 取当前日期 */

    24 int

    gettime(TIMETYPE *t); /* 取当前时间 */

    25

    26 #endif

    27

    注:与上文的datetime.h文件比较,从该头文件第23,24行可以看到,动态函数getdate,gettime的原型定义改变了,不再使用(*getdate),(*gettime)的格式了(这种格式使用较为罗嗦).

    二、正确编译与命名动态链接库

    为了让GCC编译器生成动态链接库,编译时须加选项-shared.(这点须牢记)

    LINUX系统中,为了让动态链接库能被系统中其它程序共享,其名字应符合“lib*.so*”这种格式.如果某个动态链接库不符合此格式,则LINUX的动态链接库自动装入程序(ld.so)将搜索不到此链接库,其它程序也无法共享之.

    格式中,第一个*通常表示为简写的库名,第二个*通常表示为该库的版本号.如:在我的系统中,基本C动态链接库的名字为libc.so.6,线程pthread动态链接库的名字为libpthread.so.0等等.本文例子所生成的动态链接库的名字为libmy.so,虽没有版本号,但也符合所要求的格式.

    生成该动态链接库的维护文件makefile-lib内容如下:

    1 # makefile : 纵横软件制作中心雨亦奇编写,

    2002-03-07.

    2

    3 all : libmy.so

    4

    5 SRC = getdate.c

    gettime.c

    6

    7 TGT =

    $(SRC:.c=.o)

    8

    9 $(SRC) :

    adatetime.h

    10 @touch $@

    11

    12 %.o : %.c

    13 cc -c $?

    14

    15 # 动态链接库(libmy.so)生成

    16 libmy.so :

    $(TGT)

    17 cc -s -shared

    -o $@ $(TGT)

    18

    运行命令:

    $ make -f

    makefile-lib

    $

    即生成libmy.so库.

    注: 维护文件中,第17行用-shared选项以生成动态链接库,用-s选项以去掉目标文件中的符号表,从而减小文件长度.

    三、共享动态链接库

    3.1 动态链接库配置文件

    为了让动态链接库为系统所使用,需要维护动态链接库的配置文件--/etc/ld.so.conf.此文件内,存放着可被LINUX共享的动态链接库所在目录的名字(系统目录/lib,/usr/lib除外),各个目录名间以空白字符(空格,换行等)或冒号或逗号分隔.一般的LINUX发行版中,此文件均含一个共享目录/usr/X11R6/lib,为X

    window窗口系统的动态链接库所在的目录.

    下面看看我的系统中此文件的内容如何:

    # cat

    /etc/ld.so.conf

    /usr/X11R6/lib

    /usr/zzz/lib

    #

    由上可以看出,该动态库配置文件中,增加了一个/usr/zzz/lib目录.这是我自己新建的共享库目录,下面存放我新开发的可供系统共享的动态链接库.

    3.2 动态链接库管理命令

    为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig.此执行程序存放在/sbin目录下.

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

    ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令.

    ldconfig命令行用法如下:

    ldconfig

    [-v|--verbose] [-n] [-N] [-X] [-f CONF] [-C CACHE] [-r ROOT] [-l]

    [-p|--print-cache] [-c FORMAT] [--format=FORMAT] [-V] [-?|--help|--usage]

    path...

    ldconfig可用的选项说明如下:

    (1) -v或--verbose

    : 用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,还有它所创建的连接的名字.

    (2) -n : 用此选项时,ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib,/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录.

    (3) -N : 此选项指示ldconfig不重建缓存文件(/etc/ld.so.cache).若未用-X选项,ldconfig照常更新文件的连接.

    (4) -X : 此选项指示ldconfig不更新文件的连接.若未用-N选项,则缓存文件正常更新.

    (5) -f CONF : 此选项指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf.

    (6) -C CACHE : 此选项指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,此文件存放已排好序的可共享的动态链接库的列表.

    (7) -r ROOT : 此选项改变应用程序的根目录为ROOT(是调用chroot函数实现的).选择此项时,系统默认的配置文件/etc/ld.so.conf,实际对应的为ROOT/etc/ld.so.conf.如用-r

    /usr/zzz时,打开配置文件/etc/ld.so.conf时,实际打开的是/usr/zzz/etc/ld.so.conf文件.用此选项,可以大大增加动态链接库管理的灵活性.

    (8) -l : 通常情况下,ldconfig搜索动态链接库时将自动建立动态链接库的连接.选择此项时,将进入专家模式,需要手工设置连接.一般用户不用此项.

    (9) -p或--print-cache

    : 此选项指示ldconfig打印出当前缓存文件所保存的所有共享库的名字.

    (10) -c FORMAT 或

    --format=FORMAT : 此选项用于指定缓存文件所使用的格式,共有三种:old(老格式),new(新格式)和compat(兼容格式,此为默认格式).

    (11) -V : 此选项打印出ldconfig的版本信息,而后退出.

    (12) -? 或 --help 或

    --usage : 这三个选项作用相同,都是让ldconfig打印出其帮助信息,而后退出.

    举三个例子:

    例1:

    # ldconfig -p

    793 libs found in

    cache `/etc/ld.so.cache'

    libzvt.so.2

    (libc6) => /usr/lib/libzvt.so.2

    libzvt.so (libc6)

    => /usr/lib/libzvt.so

    libz.so.1.1.3

    (libc6) => /usr/lib/libz.so.1.1.3

    libz.so.1 (libc6)

    => /lib/libz.so.1

    ......

    #

    注: 有时候用户想知道系统中有哪些动态链接库,或者想知道系统中有没有某个动态链接库,这时,可用-p选项让ldconfig输出缓存文件中的动态链接库列表,从而查询得到.例子中,ldconfig命令的输出结果第1行表明在缓存文件/etc/ld.so.cache中找到793个共享库,第2行开始便是一系列共享库的名字及其全名(绝对路径).因为实际输出结果太多,为节省篇幅,以......表示省略的部分.

    例2:

    # ldconfig -v

    /lib:

    liby.so.1 ->

    liby.so.1

    libnss_wins.so

    -> libnss_wins.so

    ......

    /usr/lib:

    libjscript.so.2

    -> libjscript.so.2.0.0

    libkspell.so.2

    -> libkspell.so.2.0.0

    ......

    /usr/X11R6/lib:

    libmej-0.8.10.so

    -> libmej-0.8.10.so

    libXaw3d.so.7

    -> libXaw3d.so.7.0

    ......

    #

    注: ldconfig命令在运行正常的情况下,默认不输出什么东西.本例中用了-v选项,以使ldconfig在运行时输出正在扫描的目录及搜索到的共享库,用户可以清楚地看到运行的结果.执行结束后,ldconfig将刷新缓存文件/etc/ld.so.cache.

    例3:

    # ldconfig

    /usr/zhsoft/lib

    #

    注: 当用户在某个目录下面创建或拷贝了一个动态链接库,若想使其被系统共享,可以执行一下"ldconfig

    目录名"这个命令.此命令的功能在于让ldconfig将指定目录下的动态链接库被系统共享起来,意即:在缓存文件/etc/ld.so.cache中追加进指定目录下的共享库.本例让系统共享了/usr/zhsoft/lib目录下的动态链接库.需要说明的是,如果此目录不在/lib,/usr/lib及/etc/ld.so.conf文件所列的目录里面,则再度运行ldconfig时,此目录下的动态链接库可能不被系统共享了.

    3.3 动态链接库如何共享

    了解了以上知识,我们可以采用以下三种方法来共享动态链接库:(注:均须在超级用户状态下操作,以我的动态链接库libmy.so共享过程为例)

    (1)拷贝动态链接库到系统共享目录下,或在系统共享目录下为该动态链接库建立个连接(硬连接或符号连接均可,常用符号连接).这里说的系统共享目录,指的是LINUX动态链接库存放的目录,它包含/lib,/usr/lib以及/etc/ld.so.conf文件内所列的一系列目录.

    # cp libmy.so

    /lib

    # ldconfig

    #

    或:

    # ln -s

    `pwd`/libmy.so /lib

    # ldconfig

    #

    (2)将动态链接库所在目录名追加到动态链接库配置文件/etc/ld.so.conf中.

    # pwd >>

    /etc/ld.so.conf

    # ldconfig

    #

    (3)利用动态链接库管理命令ldconfig,强制其搜索指定目录,并更新缓存文件,便于动态装入.

    # ldconfig `pwd`

    #

    需要说明的是,这种操作方法虽然有效,但效果是暂时的,供程序测试还可以,一旦再度运行ldconfig,则缓存文件内容可能改变,所需的动态链接库可能不被系统共享了.与之相比较,前两种方法是可靠的方法,值得业已定型的动态链接库共享时采用.前两种方法还有一个特点,即最后一条命令都是ldconfig,也即均需要更新一下缓存文件,以确保动态链接库的共享生效.

    四、含有动态函数的程序的编译

    4.1 防止编译因未指定动态链接库而出错

    当一个程序使用动态函数时,编译该程序时就必须指定含所用动态函数的动态链接库,否则编译将会出错退出.如本文示例程序ady.c的编译(未明确引用动态链接库libmy.so):

    # cc -o ady ady.c

    /tmp/ccL4FsJp.o:

    In function `main':

    /tmp/ccL4FsJp.o(.text+0x43):

    undefined reference to `gettime'

    collect2: ld

    returned 1 exit status

    #

    注: 因为ady.c所含的动态函数getdate,gettime不在系统函数库中,所以连接时出错.

    4.2 编译时引用动态链接库的几种方式

    (1)当所用的动态链接库在系统目录(/lib,/usr/lib)下时,可用编译选项-l来引用.即:

    # cc -lmy -o ady

    ady.c

    #

    注:编译时用-l选项引用动态链接库时,库名须使用其缩写形式.本例的my,表示引用libmy.so库.若引用光标库libncurses.so,须用-lncurses.注意,-l选项与参数之间不能有空格,否则会出错.

    (2)当所用的动态链接库在系统目录(/lib,/usr/lib)以外的目录时,须用编译选项-L来指定动态链接库所在的目录(供编译器查找用),同时用-l选项指定缩写的动态链接库名.即:

    # cc

    -L/usr/zzz/lib -lmy -o ady ady.c

    #

    (3)直接引用所需的动态链接库.即:

    # cc -o ady ady.c

    libmy.so

    #

    # cc -o ady ady.c

    /lib/libmy.so

    #

    等等.其中,动态链接库的库名可以采用相对路径形式(文件名不以/开头),也可采用绝对路径形式(文件名以/开头).

    五、动态链接程序的运行与检查

    5.1 运行

    编译连接好含动态函数的程序后,就可以运行它了.动态链接程序因为共享了系统中的动态链接库,所以其空间占用很小.但这并不意味功能的减少,它的执行与静态连接的程序执行,效果完全相同.在命令提示符下键入程序名及相关参数后回车即可,如下例:

    $ ady

    动态链接库高级应用示范

    当前日期:

    2002-03-11

    当前时间:19:39:06

    $

    5.2 检查

    检查什么?检查动态链接程序究竟需要哪些共享库,系统中是否已有这些库,没有的话,用户好想办法把这些库装上.

    怎么检查呢?这里,告诉你一个实用程序--ldd,这个程序就是专门用来检查动态链接程序依赖哪些共享库的.

    ldd命令行用法如下:

    ldd [--version]

    [-v|--verbose] [-d|--data-relocs] [-r|--function-relocs] [--help] FILE...

    各选项说明如下:

    (1) --version : 此选项用于打印出ldd的版本号.

    (2) -v 或

    --verbose : 此选项指示ldd输出关于所依赖的动态链接库的尽可能详细的信息.

    (3) -d 或

    --data-relocs : 此选项执行重定位,并且显示不存在的函数.

    (4) -r 或

    --function-relocs : 此选项执行数据对象与函数的重定位,同时报告不存在的对象.

    (5) --help : 此选项用于打印出ldd的帮助信息.

    注: 上述选项中,常用-v(或--verbose)选项.

    ldd的命令行参数为FILE...,即一个或多个文件名(动态链接程序或动态链接库).

    例1:

    $ ldd ady

    libmy.so =>

    ./libmy.so (0x40026000)

    libc.so.6 =>

    /lib/libc.so.6 (0x40028000)

    /lib/ld-linux.so.2

    => /lib/ld-linux.so.2 (0x40000000)

    $

    注: 每行=>前面的,为动态链接程序所需的动态链接库的名字,而=>后面的,则是运行时系统实际调用的动态链接库的名字,所需的动态链接库在系统中不存在时,=>后面将显示"not

    found",括号所括的数字为虚拟的执行地址.本例列出ady所需的三个动态链接库,其中libmy.so为自己新建的动态链接库,而libc.so.6与/lib/ld-linux.so.2均为系统的动态链接库,前一个为基本C库,后一个动态装入库(用于动态链接库的装入及运行).

    例2:

    $ ldd -v ady

    libmy.so =>

    ./libmy.so (0x40026000)

    libc.so.6 =>

    /lib/libc.so.6 (0x40028000)

    /lib/ld-linux.so.2

    => /lib/ld-linux.so.2 (0x40000000)

    Version

    information:

    ./ady:

    libc.so.6

    (GLIBC_2.1.3) => /lib/libc.so.6

    libc.so.6

    (GLIBC_2.0) => /lib/libc.so.6

    ./libmy.so:

    libc.so.6

    (GLIBC_2.1.3) => /lib/libc.so.6

    libc.so.6

    (GLIBC_2.0) => /lib/libc.so.6

    /lib/libc.so.6:

    ld-linux.so.2

    (GLIBC_2.1.1) => /lib/ld-linux.so.2

    ld-linux.so.2

    (GLIBC_2.2.3) => /lib/ld-linux.so.2

    ld-linux.so.2

    (GLIBC_2.1) => /lib/ld-linux.so.2

    ld-linux.so.2

    (GLIBC_2.2) => /lib/ld-linux.so.2

    ld-linux.so.2

    (GLIBC_2.0) => /lib/ld-linux.so.2

    $

    注:本例用-v选项以显示尽可能多的信息,所以例中除列出ady所需要的动态链接库外,还列出了程序所需动态链接库版本方面的信息.

    小结:在LINUX动态链接库的高级应用中,关键有两点,一是如何让动态链接库为LINUX系统所共享,二是编译连接程序时如何做.让动态链接库为系统所共享,主要是用ldconfig管理命令,维护好系统共享库的缓存文件/etc/ld.so.cache.编译连接时如何做?注意连接上所用的动态链接库就可以了.LINUX动态链接库的高级应用,用一用就明白:其实,就是这么简单!

    展开全文
  • 大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,...

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需装入,同时其执行代码可在多个执行程序间共享,节省了空间,提高了效率,具备很高的灵活性,得到越来越多程序员和用户的青睐。那么,在LINUX系统中有无这样的函数库呢?

    答案是肯定的,LINUX的动态链接库不仅有,而且为数不少。在/lib目录下,就有许多以.so作后缀的文件,这就是LINUX系统应用的动态链接库,只不过与WINDOWS叫法不同,它叫so,即Shared Object,共享对象。(在LINUX下,静态函数库是以.a作后缀的) X-WINDOW作为LINUX下的标准图形窗口界面,它本身就采用了很多的动态链接库(在/usr/X11R6/lib目录下),以方便程序间的共享,节省占用空间。著名的APACHE网页服务器,也采用了动态链接库,以便扩充程序功能。你只需将PHP动态链接库拷到其共享目录,修改一下配置,APACHE就可以支持PHP网页了。如果你愿意,可以自己编写动态链接库,让APACHE支持你自己定义的网页格式。这就是动态链接的好处。

    1、LINUX下动态链接库的创建

    在LINUX系统下,创建动态链接库是件再简单不过的事情。只要在编译函数库源程序时加上-shared选项即可,这样所生成的执行程序即为动态链接库。从某种意义上来说,动态链接库也是一种执行程序。按一般规则,程序名应带.so后缀。下面举个例子说说。我准备编写两个函数,一个用于查询当前日期getdate,一个用于查询当前时间gettime,并将这两个函数存于动态链接库my.so中。为此,需要做以下几项工作。

    1.1 编写用户接口文件datetime.h,内容如下(每行前面的数字为行号):

    /* datetime.h :*/

    #ifndef __DATETIME_H

    #define __DATETIME_H

    /* 日期结构 */

    typedef struct

    {

    int year;

    int mon;

    int day;

    }DATETYPE;

    /* 时间结构 */

    typedef struct

    {

    char hour;

    char min;

    char sec;

    } TIMETYPE;

    /* 函数原型说明 */

    #ifdef SHARED

    int (*getdate)(DATETYPE *d);

    #else

    int getdate(DATETYPE *d);

    #endif

    #ifdef SHARED

    int (*gettime)(TIMETYPE *t);

    #else

    int gettime(TIMETYPE *t);

    #endif

    #endif

    这个用户接口文件中,先定义了日期与时间结构,接着定义一下函数的原型。动态函数与静态函数的原型说明不同的是,动态函数应使用(*函数名)的形式,以便引用其指针。若要引用文件中的动态函数说明,用户应该定义一下SHARED宏,这样才能使用。

    1.2 编写getdate.c,源程序如下:

    /* getdate.c : */

    #include "time.h"

    #include "datetime.h"

    int getdate(DATETYPE *d)

    {

    long ti;

    struct tm *tm;

    time(&ti);

    tm=localtime(&ti);

    d->year=tm->tm_year+1900;

    d->mon=tm->tm_mon+1;

    d->day=tm->tm_mday;

    }

    在getdate函数中,先调用time取得以秒计的系统时间,再用localtime函数转换一下时间结构,最后调整得到正确的日期。

    1.3 编写gettime.c,源程序如下:

    /* gettime.c :  */

    #include "time.h"

    #include "datetime.h"

    int gettime(TIMETYPE *t)

    {

    long ti;

    struct tm *tm;

    time(&ti);

    tm=localtime(&ti);

    t->hour=tm->tm_hour;

    t->min=tm->tm_min;

    t->sec=tm->tm_sec;

    }

    gettime函数与getdate函数相仿,先用time函数取得以秒计的系统时间,再用localtime函数转换一下时间结构,最后返回当前的时间(不需调整)。

    1.4 编写维护文件makefile-lib,内容如下:

    # makefile-lib : .

    all : my.so

    SRC = getdate.c gettime.c

    TGT = $(SRC:.c=.o)

    $(SRC) : datetime.h

    @touch $@

    %.o : %.c

    cc -c $?

    # 动态函数库(my.so)生成

    my.so : $(TGT)

    cc -shared -o $@ $(TGT)

    编写维护文件的目的,在于方便程序员维护程序,尤其是维护比较大的工程项目。一个素质良好的程序员应该学会熟练地编写维护文件makefile。定义了文件间的依赖关系后,一旦源文件发生变化,仅需make一下,其目标文件维护代码会自动执行,从而自动更新目标文件,减少了许多工作量。

    注意: 每行维护代码必须以TAB(跳格键)开始,不是的话make时将出错。本维护文件第1行是注释行,以#号开头;

    文件第3行定义所有需要维护的函数库;

    第5行定义相关源程序文件;第7行定义目标文件;

    第9-10行说明所有源程序依赖于datetime.h头文件,并有相应维护代码,即touch一下,更新一下源文件的时间;

    第12-13行定义.o文件依赖于相应的.c文件,并指定了维护代码,即用cc编译一下;

    第16-17行定义共享库my.so依赖的目标文件,维护代码中用-shared编译选项,以生成动态链接库my.so。

    1.5 运行make -f makefile-lib 命令

    make运行后,动态链接库my.so就产生了,我们就可以在程序中调用了。如果想让系统所有用户都可以使用,则应以root用户登录系统,将这个库拷贝到/lib目录下(命令:cp my.so /lib),或者在/lib目录下建个符号连接即可(命令:ln -s `pwd`/my.so /lib)。

    2、LINUX下动态链接库的使用

    2.1 重要的dlfcn.h头文件

    LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。下面详细说明一下这些函数。

    2.1.1 dlerror

    原型为: const char *dlerror(void);

    当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为

    NULL时表示操作函数执行成功。

    2.1.2 dlopen

    原型为: void *dlopen (const char *filename, int flag);

    dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

    filename: 如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该

    文件。

    (1) 用户环境变量中的LD_LIBRARY值;

    (2) 动态链接缓冲文件/etc/ld.so.cache

    (3) 目录/lib,/usr/lib

    flag表示在什么时候解决未定义的符号(调用)。取值有两个:

    1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。

    2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。

    dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。

    2.1.3 dlsym : 取函数执行地址

    原型为: void *dlsym(void *handle, char *symbol);

    dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函

    数的执行代码地址。由此地址,可以带参数执行相应的函数。

    如程序代码: void (*add)(int x,int y); /* 说明一下要调用的动态函数add */

    add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址 */

    add(89,369); /* 带两个参数89和369调用add函数 */

    2.1.4 dlclose : 关闭动态链接库

    原型为: int dlclose (void *handle);

    dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

    2.2 在程序中使用动态链接库函数

    2.2.1 程序范例

    下面的程序装载了动态链接库my.so,并用getdate,gettime取得当前日期与

    时间后输出。

    #include "stdio.h" /* 包含标准输入输出文件 */

    #include "dlfcn.h" /* 包含动态链接功能接口文件 */

    #define SOFILE "./my.so" /* 指定动态链接库名称 */

    #define SHARED /* 定义宏,确认共享,以便引用动态函数 */

    #include "datetime.h" /* 包含用户接口文件 */

    main()

    {

    DATETYPE d;

    TIMETYPE t;

    void *dp;

    char *error;

    puts("动态链接库应用示范");

    dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */

    if (dp==NULL) /* 若打开失败则退出 */

    {

    fputs(dlerror(),stderr);

    exit(1);

    }

    getdate=dlsym(dp,"getdate"); /* 定位取日期函数 */

    error=dlerror(); /* 检测错误 */

    if (error) /* 若出错则退出 */

    {

    fputs(error,stderr);

    exit(1);

    }

    getdate(&d); /* 调用此共享函数 */

    printf("当前日期: %04d-%02d-%02d

    ",d.year,d.mon,d.day);

    gettime=dlsym(dp,"gettime"); /* 定位取时间函数 */

    error=dlerror(); /* 检测错误 */

    if (error) /* 若出错则退出 */

    {

    fputs(error,stderr);

    exit(1);

    }

    gettime(&t); /* 调用此共享函数 */

    printf("当前时间: %02d:%02d:%02d

    ",t.hour,t.min,t.sec);

    dlclose(dp); /* 关闭共享库 */

    exit(0); /* 成功返回 */

    }

    程序说明:

    第8行: 包含标准输入输出头文件,因为程序中使用了printf,puts,fputs等标准输入输出函数,需要让编译器根据头文件中函数的原型,检查一下语法;

    第10-11行: 包含动态链接库功能头文件,并定义动态链接库名称;

    第13-14行: 定义宏SHARED以便引用14行的头文件datetime.h中的动态函数说明;

    第25行: 用dlopen打开SOFILE共享库,返回句柄dp;

    第27-31行: 检测dp是否为空,为空则显示错误后退出;

    第33行: 用dlsym取得getdate函数动态地址;

    第35-40行: 如果dlerror返回值不为空,则dlsym执行出错,程序显示错误后退出;

    第42-43行: 执行getdate调用,输出当前日期;

    第45行: 用dlsym取得gettime函数动态地址;

    第47-52行: 如果dlerror返回值不为空,则dlsym执行出错,程序显示错误后退出;

    第54-55行: 执行gettime调用,输出当前时间;

    第57行: 用dlclose关闭dp所指示的动态链接库;

    第59行: 程序退出,返回0值。

    2.2.2 编写维护文件

    维护文件makefile内容如下:

    # makefile : 纵横软件制作中心雨亦奇编写, 2001-06-28.

    all : dy

    DYSRC = dy.c

    DYTGT = $(DYSRC:.c=.o)

    %.o : %.c

    cc -c $?

    # 动态库应用示范程序

    dy : $(DYTGT)

    cc -rdynamic -s -o $@ $(DYTGT) -ldl

    维护文件说明:

    第3行: 定义所有需要维护的模块;

    第5行: 定义源程序;

    第7行: 定义目标文件;

    第9-10行: 定义.o文件依赖于.c文件,维护代码为“cc -c 变动的源文件名”;

    第13-14行: 定义dy依赖于变量DYTGT指示的值,维护代码中采用-rdynamic选项以指定输出文件为动态链接的方式,选项-s指定删除目标文件中的符号表,最后的选项-ldl则指示装配程序ld需要装载dl函数库。

    2.2.3 运行make命令

    运行make后将产生执行文件dy,运行后将产生如下类似信息:

    动态链接库应用示范

    当前日期: 2001-06-28

    当前时间: 10:06:21

    当删除my.so文件时,将出现以下信息:

    动态链接库应用示范

    my.so: cannot open shared object file: 文件或目录不存在

    3、小结

    LINUX创建与使用动态链接库并不是一件难事。编译函数源程序时选用-shared选项即可创建动态链接库,注意应以.so后缀命名,最好放到公用库目录(如/lib,/usr/lib等)下面,并要写好用户接口文件,以便其它用户共享。使用动态链接库,源程序中要包含dlfcn.h头文件,写程序时注意dlopen等函数的正确调用,编译时要采用-rdynamic选项与-ldl选项,以产生可调用动态链接库的执行代码。

    展开全文
  • /tmp/cc8LkErr.o: In function `main':test.c:(.text+0x12): undefined reference to `hello'collect2: ld \u8fd4\u56de 1不能找到函数hello3添加链接库后编译gcc test.c -lhello -L.4.运行a.out$ ./a.out./a.out: ...

    /tmp/cc8LkErr.o: In function `main':

    test.c:(.text+0x12): undefined reference to `hello'

    collect2: ld \u8fd4\u56de 1

    不能找到函数hello

    3添加链接库后编译

    gcc test.c -lhello -L.

    4.运行a.out

    $ ./a.out

    ./a.out: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

    不能找到链接库libhello.so

    5检测4的错误原因

    $ ldd a.out

    linux-gate.so.1 => (0x00110000)

    libhello.so => not found

    libc.so.6 => /lib/libc.so.6 (0x00879000)

    /lib/ld-linux.so.2 (0x00859000)

    提示libhello.so这个库文件没有找到

    6.添加环境变量

    $ export LD_LIBRARY_PATH=/mnt:$LD_LIBRARY_PATH

    ./a.out

    hello7.现在检查

    $ ldd a.out

    linux-gate.so.1 => (0x00110000)

    libhello.so => /mnt/libhello.so (0x00111000)

    libc.so.6 => /lib/libc.so.6 (0x00879000)

    /lib/ld-linux.so.2 (0x00859000)

    一切OK了

    添加环境变量的方式有很多种

    比如/etc/ld.so.conf

    ~目下的.bash_profile都可以

    展开全文
  • Linux中加载动态链接库的三种方法:第一种是修改系统文件:在/etc/ld.so.conf文件中指定了默认的动态链接库查找路径,我的/etc/ld.so.conf文件内容是这样的include /etc/ld.so.conf.d/*.conf也就是说它间接的指定了...
  • 资料出处:http://linux.chinaitlab.com/administer/803560.html编 写维护文件的目的,在于方便程序员维护程序,尤其是维护比较大的工程项目。一个素质良好的程序员应该学会熟练地编写维护文件makefile。定义了文件 ...
  • linux动态链接库的生成1、gcc 下动态链接库的生成Linux下动态库文件的扩展名为".so"(Shared?Object)。按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号)。这样,线程函数库被称作libthread....
  • 还是最近项目中遇到的问题,是关于动态库的,这里做个总结。linux文件我们在某个程序文件中写了一段通用性比较浅的代码,比如某个算法,或者某个操作,通常会在其他的项目或者文件中使用到这部分功能,我们当然...
  • 上一篇文章我们从 Linux C 编程的角度分析了一下 Linux 中的静态链接库和动态链接库的区别,这篇文章着重从 Linux 编译和运行的角度分析一下 Linux 动态链接库的查找问题。 一、编译期间动态链接库报错 Linux下编译...
  • 关于Linux和Unix动态连接的安全实际上所有程序执行都依赖于。在包括Linux的大多数现代类Unix系统中,程序缺省使用动态连接(DLL)进行编译。这样就可以更新某个,所有使用该的程序如果可能的话,都将使用新...
  • 动态链接库应用示范 my.so: cannot open shared object file: 文件或目录不存在 3、小结 Linux创建与使用动态链接库并不是一件难事。 编译函数源程序时选用-shared选项即可创建动态链接库,注意应以.so后缀命名,...
  • linux环境指定动态链接库路径创建一个动态链接库gcc -shared -fpic -o libqazwsx.so这条命令将x1.o x2.0 x3.o三个文件打包成一个动态链接库文件libqazwsx.so链接这个动态链接库,并放在可执行文件目录下,使可执行...
  • LINUX动态链接库高级应用(etc/ld.so.conf)共享动态链接库3.1 动态链接库配置文件为了让动态链接库为系统所使用,需要维护动态链接库的配置文件--/etc/ld.so.conf.此文件内,存放着可被LINUX共享的动态链接库所在目录的...
  • 动态链接库管理命令Ldconfig使用说明Linux系统中,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令——ldconfig.1. ldconfig命令的用途:主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/...
  • /** author: hjjdebug* date: 2012* title: linux 动态链接库创建和使用--动态连接*/动态连接,链接程序(gcc等)链接时无需指定第三方动态连接库,而是由调用者显式调用指定库,并获取对应库的函数入口地址linux ...
  • Windows与Linux动态链接库的区别

    万次阅读 2021-02-27 18:32:19
    使用CMake创建动态链接库时,会生成两个文件,比如 下面代码是在CMakeLists.txt中描述的依赖关系,在cmake构建过程中,会在上下文规定的路径中寻找“libcurldll.a”、“libbase64.a”,即在前后分别自动添加上...
  • 无论静态,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。在系统提示符下键入以下命令得到hello.o文件。# gcc -c hello.c#(注1:本文不介绍各命令使用和其参数功能,若...
  • 也可配置全局环境变量用相对路径)(2)在CMakeLists.txt或集成开发环境中指定库函数的动态链接库或者静态链接库所在的文件夹路径(3)在CMakeLists.txt或集成开发环境...
  • 这两天在玩QT,准备做一个任务管理器类似的动态线图,找了一会儿决定用QWT。昨天,先是找fedora的源,装了一个5.0.x的,但是我的QT装的比较混乱,装的QT4,(后来发现原先系统带qt3,命令行make,make install,qwt...
  • } 头文件slstrlen.h #ifndef SLSTRLEN_H #define SLSTRLEN_H #include "slstrlen_global.h" //如果动态库使用g++编译,那么动态库定义函数的时候加上extern "C",否则会提示undefined symbol错误。 extern "C" int ...
  • Qt加载动态链接库

    2020-12-20 18:00:48
    先制作个简单的动态链接库,再在Qt里面加载它。【制作动态链接库】先...5 }在Linux下编译,生成hello.o:gcc -c hello.c编译成动态链接库libhello.so(注意:Linux下的动态链接库以lib开始命名):gcc -shared -o li...
  • Linux动态链接库技术分析和移植技巧 (1)摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,...
  • 选择共享库,取个该动态链接库的名字,下一步4.继续下一步,到Modules界面,默认选择QtCore(QtCore模块提供核心的非图形用户接口功能,所有其他Qt模块都依赖于这个模块,如果您使用qmake来构建您的项目,则默认将...
  • Linux共享路径配置  Linux下找不到共享文件的典型现象为明明已经安装某个软包(如libnet,MySQL),编译连接可以正常进行,但是在运行时出现如“error while loading shared libraries: libnet.so.1:cannot ...
  • error whilel oading shared ...一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object fi
  • 动态库 编译过程 C语言的编译链接过程就是由源代码产生可执行文件的过程,主要包括预处理->编译(汇编)->链接三个过程。 预处理 将test.c/cpp/asm文件处理为中间文件,过程包括了对伪指令(宏定义,条件编译...
  • #include #include "mytestso.h"int main(int argc, char** argv){void* pdlhandle;char* pszerror;int a, b;char* psztxt = "1024";// open mytestso.sopdlhandle = dlopen("./mytestso.so", RTLD_LAZY);...
  • 大家都知道,在 WINDOWS 系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library),大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态...
  • 动态库文件的扩展名为".so"(Shared Object)。按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号)。这样,线程函数被称作 libthread.so。静态的文件名形式是libname.a。共享archive的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 107,602
精华内容 43,040
关键字:

linux创建动态链接库

linux 订阅