Linux 静态链接库和动态连接库

(0)文件夹

VMware
下安装Ubuntu的吐血经历

零基础学习Shell编程

Linux下的makefile的妙用

Linux调试神器
-- gdb

十分钟学会Python的基本类型

Linux
静态链接库和动态连接库

一:静态链接库的应用  三步走~~~

##g++ -c StaticMath.cpp

##ar -crv libstaticmath.a StaticMath.o

##g++ -o run test_a.cpp -L. -lstaticmath

#[@sjs_37_33 lib_A_SO]# ./run

a + b = 12

a - b = 8

a * b = 20

a / b = 5

**********************

**********************

sh: pause: command not found

**********************

二:走的弯路~~~~

#[@sjs_37_33 lib_A_SO]# g++ -o run test_a.cpp  // 缺少依赖库文件

/tmp/ccx8rZph.o: In function `main‘:

test_a.cpp:(.text+0x39): undefined reference to `StaticMath::add(double, double)‘

test_a.cpp:(.text+0x76): undefined reference to `StaticMath::sub(double, double)‘

test_a.cpp:(.text+0xb3): undefined reference to `StaticMath::mul(double, double)‘

test_a.cpp:(.text+0xf0): undefined reference to `StaticMath::div(double, double)‘

test_a.cpp:(.text+0x12a): undefined reference to `StaticMath::StaticMath()‘

test_a.cpp:(.text+0x136): undefined reference to `StaticMath::print()‘

test_a.cpp:(.text+0x151): undefined reference to `StaticMath::~StaticMath()‘

test_a.cpp:(.text+0x16d): undefined reference to `StaticMath::~StaticMath()‘

collect2: ld ?μ?? 1

#[@sjs_37_33 lib_A_SO]# g++ -o run test_a.cpp -L. -lstaticmath // 缺少依赖库?非也。缺少实现函数即.cpp没有实现.h中的文件

/tmp/cczojb8v.o: In function `main‘:

test_a.cpp:(.text+0x12a): undefined reference to `StaticMath::StaticMath()‘

test_a.cpp:(.text+0x151): undefined reference to `StaticMath::~StaticMath()‘

test_a.cpp:(.text+0x16d): undefined reference to `StaticMath::~StaticMath()‘

collect2: ld ·μ?

? 1

三: 动态库的应用 两步走~~·

###  g++ -fPIC -shared -o libdynmath.so StaticMath.cpp  ---- 生成-o libdynmath.so 动态库

引用动态库编译成可运行文件(跟静态库方式一样):

###g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath

然后执行:./a.out,发现居然报错了!

。!

#[@sjs_37_33 lib_A_SO]# ./a.out

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

那么,在运行的时候是怎样定位共享库文件的呢?

1)        当系统载入可运行代码时候,可以知道其所依赖的库的名字。可是还须要知道绝对路径。

此时就须要系统动态载入器(dynamic linker/loader)。

2)        对于elf格式的可运行程序。是由ld-linux.so*来完毕的。它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 文件夹找到库文件后将其加载内存。

怎样让系统可以找到它:

 假设安装在/lib或者/usr/lib下,那么ld默认可以找到。无需其它操作;假设安装在其它文件夹。须要将其加入到/etc/ld.so.cache文件里。过程例如以下:

编辑/etc/ld.so.conf文件,增加库文件所在文件夹的路径。执行ldconfig 。该命令会重建/etc/ld.so.cache文件;我们将创建的动态库拷贝到/usr/lib以下,然后执行測试程序,成功。

四:  Linux下库相关命令

##ldd libdynmath.so

linux-vdso.so.1 =>  (0x00007fffed837000)

libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f48b0413000)

libm.so.6 => /lib64/libm.so.6 (0x00007f48b018e000)

libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f48aff78000)

libc.so.6 => /lib64/libc.so.6 (0x00007f48afbe8000)

/lib64/ld-linux-x86-64.so.2 (0x0000003da7800000)

g++(gcc)编译选项

  -shared :指定生成动态链接库。

-static :指定生成静态链接库。

-fPIC :表示编译为位置独立的代码,用于编译共享库。目标文件须要创建成位置无关码, 念上就是在可运行程序装载它们的时候,它们能够放在可运行程序的内存里的不论什么地方。

-L. :表示要连接的库所在的文件夹。

-l:指定链接时须要的动态库。

编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib。后面加上.a/.so来确定库的名称。

-Wall :生成全部警告信息。

  -ggdb :此选项将尽可能的生成gdb 的能够使用的调试信息。

-g :编译器在编译的时候产生调试信息。

-c :仅仅激活预处理、编译和汇编,也就是把程序做成目标文件(.o文件) 。

-Wl,options :把參数(options)传递给链接器ld 。

假设options 中间有逗号,就将options分成多个选项,然后传递给链接程序。

nm命令

有时候可能须要查看一个库中究竟有哪些函数,nm命令能够打印出库中的涉及到的全部符号。

库既能够是静态的也能够是动态的。

nm列出的符号有非常多,常见的有三种:

一种是在库中被调用。但并没有在库中定义(表明须要其它库支持)。用U表示;

一种是库中定义的函数,用T表示,这是最常见的;

一种是所谓的弱态”符号,它们尽管在库中被定义,可是可能被其它库中的同名符号覆盖。用W表示。

$nm libhello.h

ldd命令

ldd命令能够查看一个可运行程序依赖的共享库,比如我们编写的四则运算动态库依赖以下这些库:

打开文件、保存、关闭文件(vi命令模式下使用)

vi filename       //打开filename文件

:w       //保存文件

:w vpser.net //保存至vpser.net文件

:q          //退出编辑器,假设文件已改动请使用以下的命令

:q!        //退出编辑器,且不保存

:wq         //退出编辑器,且保存文件

五:相关代码

h文件

#pragma once
class StaticMath
{
public:
    StaticMath(void);
    ~StaticMath(void);

    static double add(double a, double b);//加法
    static double sub(double a, double b);//减法
    static double mul(double a, double b);//乘法
    static double div(double a, double b);//除法

    void print();
};

cpp文件

#include "StaticMath.h"
#include <stdio.h> 

StaticMath::StaticMath(void)
{
    //
    print();
}

StaticMath::~StaticMath(void)
{
    //
    print();
}

double StaticMath::add(double a, double b)//加法
{
    return a + b;
}
double StaticMath::sub(double a, double b)//减法
{
    return a - b;
}   

double StaticMath::mul(double a, double b)//乘法
{
    return a * b;
}
double StaticMath::div(double a, double b)//除法
{
    if(0==b)
        return -1;
    return a / b;
}

void StaticMath::print()
{
    printf("**********************\n");
}

測试文件

#include "StaticMath.h" // 測试静态库libstaticmath.a 和 动态库libdynmath.so

#include <iostream>
#include <stdlib.h>
using namespace std;

int main(int argc, char* argv[])
{
    double a = 10;
    double b = 2;

    cout << "a + b = " << StaticMath::add(a, b) << endl;
    cout << "a - b = " << StaticMath::sub(a, b) << endl;
    cout << "a * b = " << StaticMath::mul(a, b) << endl;
    cout << "a / b = " << StaticMath::div(a, b) << endl;

    StaticMath sm;
    sm.print();

    system("pause");
    return 0;
}

六:总结

静态链接库与动态链接库都是共享代码的方式,假设採用静态链接库。则不管你愿不愿意,lib 中的指令都所有被直接包括在终于生成的 EXE 文件里了。

可是若使用 DLL,该 DLL 不必被包括在终于 EXE 文件里,EXE 文件运行时能够“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个差别在于静态链接库中不能再包括其它的动态链接库或者静态库。而在动态链接库中还能够再包括其它的动态或静态链接库。动态库就是在须要调用当中的函数时,依据函数映射表找到该函数然后调入堆栈运行。假设在当前project中有多处对dll文件里同一个函数的调用。那么运行时,这个函数仅仅会留下一份拷贝。

可是假设有多处对lib文件里同一个函数的调用,那么运行时,该函数将在当前程序的运行空间里留下多份拷贝,并且是一处调用就产生一份拷贝。

时间: 2024-10-26 12:00:40

Linux 静态链接库和动态连接库的相关文章

动态连接库 VS 静态连接库

一.静态库与动态库 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file).程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下.所以这些函数库被成为静态库(static libaray),通常文件名为"libxxx.a"的形式. 其实,我们也可以把对一些库函数的链接载入推迟到程序运行时期(runtime).这就是如

Qt动态连接库/静态连接库创建与使用,QLibrary动态加载库

版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt动态连接库/静态连接库创建与使用,QLibrary动态加载库     本文地址:http://techieliang.com/2017/12/680/ 文章目录 1. 动态连接库创建与使用  1.1. 项目创建  1.2. 调用-使用.h文件 2. 静态库创建及使用  2.1. 创建  2.2. 使用 3. QLibrary动态加载动态库  3.1. 介绍  3.2. 范例  3.3.

[C] linux静态链接库与动态链接库详解

http://blog.chinaunix.net/u2/76292/showart.php?id=1274181 一顺便说说了哦  通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file).程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下.所以这些函数库被成为静态库(static libaray),通常文件名为"libxx

Linux下的动态连接库及其实现机制

Linux与Windows的动态连接库概念相似,但是实现机制不同.它引入了GOT表和PLT表的概念,综合使用了多种重定位项,实现了"浮动代码",达到了更好的共享性能.本文对这些技术逐一进行了详细讨论. 本文着重讨论x86体系结构,这是因为 (1)运行Linux的各种体系结构中,以x86最为普及: (2)该体系结构上的Windows操作系统广为人知,由此可以较容易的理解Linux的类似概念: 下表列出了Windows与Linux的近义词,文中将不加以区分: Windows Linux 动

linux(debian) 安装软件,缺少动态连接库.so

有以下几种提示: 1.缺少动态连接库.so-cannot open shared object file:No such file or directory 2.缺少动态连接库.so.0-cannot open shared object file:No such file or directory 3.缺少动态连接库.so.1-cannot open shared object file:No such file or directory 可以直接: # sudo ldconfig 再编译,如

创建线程消息循环服务于动态连接库

因为动态连接库需要对DBT_DEVICEARRIVAL.DBT_DEVICEREMOVECOMPLETE等消息的处理,所以拿一个不太理想的usb-hid的dll来说明,不多说直接上代码 1 // 下列 ifdef 块是创建使从 DLL 导出更简单的 2 // 宏的标准方法.此 DLL 中的所有文件都是用命令行上定义的 WIN32USB_EXPORTS 3 // 符号编译的.在使用此 DLL 的 4 // 任何其他项目上不应定义此符号.这样,源文件中包含此文件的任何其他项目都会将 5 // WIN

linux静态链接库与动态链接库详解

转:http://bbs.chinaunix.net/thread-1281954-1-1.html 二动态链接库的特点与优势  首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:  1.可以实现进程之间的资源共享.   什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了.如果有,则让其共享那一个拷贝:只有没有才链接载入.这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源

C编译: 动态连接库 (.so文件)

转自:http://www.cnblogs.com/vamei/archive/2013/04/04/2998850.html 在“纸上谈兵: 算法与数据结构”中,我在每一篇都会有一个C程序,用于实现算法和数据结构 (比如栈和相关的操作).在同一个程序中,还有用于测试的main()函数,结构体定义,函数原型,typedef等等. 这样的做法非常不“环保”.算法的实际运用和算法的实现混在一起.如果我想要重复使用之前的源程序,必须进行许多改动,并且重新编译.最好的解决方案是实现模块化: 只保留纯粹的

linux 静态链接和动态链接

链接 一个可执行目标文件的生成需要经过预编译(g++ -E).编译(g++ -S).汇编(g++ -c).链接四个步骤.链接是将多个可重定位目标文件合并到一个目标文件的过程.链接由链接器完成,链接器重要完成两个任务: 1.符号(符号表由汇编器构造)解析.也就是将符号引用和符号定义关联起来.其中符号定义和符号引用可能不在同一个目标文件中.而且链接器对多重定义的全局符号的解析有一定的规则:不允许有多个同名强符号(函数和初始化了的全局变量).如果有一个强符号和多个弱符号同名选择强符号.如果有多个弱符号