静态链接库和动态链接库

共有两种库:

一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。

一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。

共有两种链接方式:

动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。

静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。

关于lib和dll的区别如下:

(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

(2)如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才行。

(3)动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。

编译生成LIB

创建win32控制台程序,勾选LIB类型。增加并编写app,生成解决方案

1>------ 已启动生成:  项目: test, 配置: Debug Win32 ------
1>  test.cpp
1>  test.vcxproj -> D:\visual studio\test\Debug\test.lib
========== 生成:  成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

编译生成DLL:

创建win32控制台程序,勾选DLL类型,创建add.h

#ifndef __ADD_H__
#define __ADD_H__
extern "C" int _declspec(dllexport) add(int x, int y);
#endif

这里注意:使用 _declspec(dllexport) 关键字从 DLL 导出数据、函数、类或类成员函数。_declspec(dllexport) 会将导出指令添加到对象文件中,如果不适用dllexport,则动态使用dll的时候找不到函数

创建add.cpp

#include "add.h"
int add(int a, int b)
{
    return a + b;
}

然后点击生成---生成解决方案,会在工程的Debug目录下生成一个DLL文件(add.dll)

1> add.vcxproj -> D:\visual studio\add\Debug\add.dll

动态调用DLL(仅需要DLL,不需要头文件和LIB)

#include <iostream>
#include <windows.h>
using namespace std;
typedef int(*FUN)(int, int);//定义指向和DLL中相同的函数原型指针
int main()
{
    int x, y;
    HMODULE hDLL = LoadLibrary("D:\\visual studio\\add\\Debug\\add.dll");//加载dll
    if (hDLL != NULL)
    {
        FUN add = FUN(GetProcAddress(hDLL, "add"));//获取导入到应用程序中的函数指针,根据方法名取得
        if (add != NULL)
        {
            cout << "Input 2 Numbers:";
            cin >> x >> y;
            cout << add(x, y) <<endl;
        }
        else
        {
            cout << "Cannot Find Function"  << endl;
        }
        FreeLibrary(hDLL);
    }
    else
    {
        cout << "Cannot Find dll"  << endl;
    }
    return 1;
}

生成结果:

Input 2 Numbers:3 4
7
请按任意键继续. . .

静态调用(同时需要头文件、LIB和DLL文件,缺一不可)

1:将dll工程下的dll和lib拷贝到测试工程中的debug文件夹

2:编写测试工程的头文件

#ifndef __USEDll_H__
#define __USEDll_H__
extern "C" _declspec(dllimport) int add(int x, int y);
#endif

3:编写cpp文件

#include "UseDll.h"
#include <iostream>
using namespace std;
#pragma comment(lib,"D:\\visual studio\\UseDll\\Debug\\add.lib")
int main()
{
    int x, y;
    cout << "Input 2 Numbers:";
    cin >> x >> y;
    cout << add(x, y) <<endl;
}

运行结果如下:

Input 2 Numbers:10 10
20
请按任意键继续. . .

说明:#pragma comment (lib,"...lib")就是告诉链接器优先链接该lib文件,除了使用此语句外,可以在工程属性-->链接器--> 输入-->附加依赖项中添加此lib。此时该lib需要放到系统路径下。

这里注意,这里的lib是生成dll的时候生成的,相对于生成lib时候产生的lib要小,其实这种是导入库,并不是静态库,静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表,各个函数地址等等,确保程序找到对应函数的一些基本地址信息。

参考文档:https://blog.csdn.net/red10057/article/details/7394213

https://blog.csdn.net/Sya_inn/article/details/53981440

http://www.cppblog.com/amazon/archive/2009/09/04/95318.html

原文地址:https://www.cnblogs.com/BGPYC/p/9008265.html

时间: 2024-10-10 13:04:30

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

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

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

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

先来说说C/C++编译过程 编译: 检查语句符号定义,将C/C++代码翻译生成中间语言. 链接: 将中间代码整合,生成可执行的二进制代码. 简单的说,库文件都是一种特殊的中间语言文件,静态库还是一种特殊格式的归档文件(打包的文件). 使用静态库: 1. 先编写库函数 1 #ifndef _PRINT_TEST_H_ 2 3 #define _PRINT_TEST_H_ 4 #ifdef __cplusplus 5 extern "C" 6 { 7 #endif 8 9 extern i

静态链接库与动态链接库

静态链接库与动态链接库都是共享代码的方式. 静态链接库(lib): 在程序执行之前完成所有的组装工作,生成一个可执行的目标文件(EXE文件). 静态库的两个特点: 链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大. 如果有多个(调用相同库函数的)进程在内存中同时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多. 动态链接库(dll&lib): 在程序装载内存的时候才真正的把库函数代码链接进行确定它们的地址,并且就算有几个程序同时运行,内存也只存在一份函数代码

C语言之静态链接库和动态链接库

1:静态链接库 比较早出现的是静态链接库.静态库其实就是商业公司将自己的函数库源代码经过只编译不连接形成.o的目标文件,然后用ar工具将.o文件归档成.a的归档文件(.a的归档文件又叫静态链接库文件).商业公司通过发布.a库文件和.h头文件来提供静态库给客户使用:客户拿到.a和.h文件后,通过.h头文件得知库中的库函数的原型,然后在自己的.c文件中直接调用这些库文件,在连接的时候链接器会去.a文件中拿出被调用的那个函数的编译后的.o二进制代码段链接进去形成最终的可执行程序. 2:动态链接库 动态

静态链接库和动态链接库的区别及优缺点

动态链接库和静态链接库的区别 本文参考了以下博客:      1. http://blog.csdn.net/gamecreating/article/details/5504152      2. http://blog.csdn.net/left_la/article/details/12098545      3. http://blog.csdn.net/augusdi/article/details/6460415 静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序

介绍静态链接库和动态链接库的区别,及在VC++6.0中的建立和使用

首先介绍一下链接库:链接库分为动态链接库和静态链接库两种 LIB是静态链接库,在程序编译连接的时候是静态链接,其对应的文件格式是.lib.即当程序采用静态链接库的时候,.lib文件中的函数被链接到最终的可执行文件中,因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行. DLL是动态链接库,在程序运行的时候被调用,其对应的文件的格式是.dll.即当程序采用动态链接的时候,.dll文件中的函数并没有被链接到可执行文件中,可执行文件只是保存了函数的地址信息.但是

[C++] 静态链接库和动态链接库的区别

静态链接库和动态链接库的区别 一.静态链接库 预编译->编译->汇编->链接 Linux: 生成目标文件 g++ -c source.cpp -o source.o 打包成静态链接库 ar -crv source.a source.o 使用静态链接库 g++ test.cpp -L静态链接库目录 -l静态链接库名称没有后缀 二.动态链接库 使用动态链接库是为了规避静态链接库的两个问题. 一个是多个副本的问题,对于静态库都是在编译时刻将其编译到源代码当中,在运行时刻不会再和静态库有任何关系

35.静态链接库和动态链接库

35.1.函数库的前世今生 (1)函数库就是一些事先写好的函数的集合,因为函数是模块化的,因此可以被复用:我们写好了某个函数,可以被反复使用,譬如A写好了某个函数然后共享出来,当B有相同的需求时就不需自己写直接用A写好的这个函数即可. (2)最开始是没有函数库的,每个人写程序都要从零开始自己写,时间长了慢慢的早期的程序员就积累下来了一些有用的函数:早期的程序员经常参加行业聚会,在聚会上大家互相交换各自的函数库:后来程序员中的一些大神就提出把大家各自的函数库收拢在一起,然后经过校准和整理,最后形成

简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

一个程序简单的程序如下: 1 hello.h #ifndef HELLO_H#define HELLO_H void hello(const char *name); #endif 2 hello.c #include <stdio.h>#include <stdlib.h> void hello(const char *name){ printf("hello %s\n",name);} 3 main.c #include <stdio.h>#in

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

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