linux 动态链接库的创建和使用--动态连接

原创 2012年03月25日 17:01:57
/*
 * author: hjjdebug
 * date: 2012
 * title: linux 动态链接库的创建和使用--动态连接
*/

动态连接,链接程序(gcc等)链接时无需指定第三方动态连接库,而是由调用者显式调用指定库,并获取对应库的函数入口地址

linux 动态链接库的创建和使用
1. 先创建一个动态链接库。源码如下:
$ cat max.cpp
extern "C"
{
    int max(int a, int b)
    {
        return a>b? a:b;
    }
}
加上extern "C", 是为了导出函数名称不用C++格式,而用C格式
编译生成动态库
g++ -shared -o libmax.so max.cpp

把库copy 到系统目录。

sudo cp libmax.so /lib

具体copy 到哪里可以用strace 跟踪一下, 它会按一定次序搜索目录加载。


2. 再创建一个测试用例,源码如下:
gitserver@gitserver-desktop:~/share/android4.0.3/hjj/pc$ cat test_d.cpp
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>    // 动态加载的函数头文件
// int max(int a, int b);
typedef int (*maxptr)(int a, int b);
int main(int argc, char *argv[])
{
        maxptr max;        // 定义max 型函数指针
        void *handle = dlopen("libmax.so",RTLD_LAZY);
        if(!handle)
        {
                printf("error open librayry libmax.so");
                exit(1);
        }
        max = (maxptr)dlsym(handle,"max");
        if(!max)
        {
                char *err=dlerror();
                printf("%s",err);
                exit(2);
        }
        int a=max(3,5);
        printf("the bigger is %d\n",a);
        dlclose(handle);
        return 0;
}

编译生成可执行文件
g++ -o test test.cpp -ldl

libdl.so 是必需的动态库

3. 运行可执行文件。
$ ./test
the bigger is 5

注意:
当没有用extern "C" 包含代码时, 运行会出现下列错误。
/lib/libmax.so: undefined symbol: max
你可以用nm 来查看libmax.so, 看其输出符号到底是什么,一看,知道应该用C 名称导出。
其它常见错误为:
1.没有包含dlfcn.h 头文件, 引起编译错误
test_d.cpp: In function ‘int main(int, char**)’:
test_d.cpp:9:36: error: ‘RTLD_LAZY’ was not declared in this scope
test_d.cpp:9:45: error: ‘dlopen’ was not declared in this scope
test_d.cpp:15:34: error: ‘dlsym’ was not declared in this scope
test_d.cpp:18:21: error: ‘dlerror’ was not declared in this scope
test_d.cpp:24:16: error: ‘dlclose’ was not declared in this scope

2.连接没有包含libdl.so, 出现连接错误
$ g++ -o test_d test_d.cpp  
/tmp/ccv8xKSN.o: In function `main':
test_d.cpp:(.text+0x19): undefined reference to `dlopen'
test_d.cpp:(.text+0x50): undefined reference to `dlsym'
test_d.cpp:(.text+0x60): undefined reference to `dlerror'
test_d.cpp:(.text+0xbd): undefined reference to `dlclose'
collect2: ld returned 1 exit status

3. 生成动态库没有采用-share 选项,出现连接错误
$ g++ -o libmax.so max.cpp
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status

4. 当动态库中调用printf 等调用时,编译需要加上 -fPIC 选项(生成位置无关代码)否则出错

/usr/bin/ld: /tmp/ccVnb7rP.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccVnb7rP.o: could not read symbols: Bad value

所以完整的编译选项是:

g++ -shared -fPIC -o libmax.so max.cpp


调试动态库与调试普通代码没有差别, 当然,要加上-g 选项才能跟踪代码调试。



版权声明:本文为博主原创文章,未经博主允许不得转载。

linux下动态链接实现原理

符号重定位 讲动态链接之前,得先说说符号重定位。 c/c++ 程序的编译是以文件为单位进行的,因此每个 c/cpp 文件也叫作一个编译单元(translation unit), 源文件先是被编译成...

LINUX动态链接库的创建与使用

一,LINUX系统中动态链接库的创建与使用 大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link...
  • jenshy
  • jenshy
  • 2006年04月24日 10:20
  • 24610

Linux动态链接库.so文件的创建与使用

1. 介绍        使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使...

linux 下动态链接库的创建与使用——dlopen,dlsym

一、引言          通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可...
  • edonlii
  • edonlii
  • 2012年12月27日 21:07
  • 8120

LINUX系统中动态链接库的创建与使用

LINUX系统中动态链接库的创建与使用       大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀 的文件,DLL即Dynamic Link Library)。这种动态...
  • leo115
  • leo115
  • 2012年03月15日 10:50
  • 466

Linux静态/动态链接库的创建和使用(转载学习)

Linux静态/动态链接库的创建和使用(转载学习) 转载地址:http://space.itpub.net/47598/viewspace-26142 和Windows系统一样Linux也有静态/...

(转)LINUX系统中动态链接库的创建和使用

原文:http://www.cnblogs.com/hoys/archive/2010/10/28/1863253.html 大家都知道,在windows系统中有非常多的动态链接库(以.dll为后缀...
  • sai1101
  • sai1101
  • 2011年12月14日 16:19
  • 186
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux 动态链接库的创建和使用--动态连接
举报原因:
原因补充:

(最多只允许输入30个字)