静态链接库LIB和动态链接库DLL

静态链接库LIB和动态链接库DLL

VS2008 lib静态链接

目录

一、静态链接库与动态链接库区别

二、LIB文件

三、DLL文件

四、实例代码

 

一、 静态链接库与动态链接库区别

     静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。 动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。如果在当前工程中有多处对dll文件中同一个函数的调用,那么执行时,这个函数只会留下一份拷贝。但是如果有多处对lib文件中同一个函数的调用,那么执行时,该函数将在当前程序的执行空间里留下多份拷贝,而且是一处调用就产生一份拷贝。 

静态链接库与静态链接库调用规则总体比较如下:

1、 静态链接库(比较简单):
首先,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件。生成库的.h头文件中的声明格式如下:
    extern "C" 函数返回类型 函数名(参数表);
    在调用程序的.cpp源代码文件中如下:
    #include "..\lib.h"
    #pragma comment(lib,"..\\debug\\libTest.lib") //指定与静态库一起链接(或者在IDE的lib栏中填入lib文件的路径,在IDE的lib目录栏填入lib所在文件夹目录)
其次因为静态链接库是将全部指令都包含入调用程序生成的EXE文件中。因此如果用的是静态链接库,那么也就不存在“导出某个函数提供给用户使用”的情况,要想用就得全要!要不就都别要!

个人理解:其实可以认为静态链接看做与直接将要链入的lib工程的源码引入编译等效,因为实际结果来看也应该是等效的,最终都只是一个exe文件,功能会是完全一样的,只是多了一些编译链接的过程.


2、 动态链接库:
动态链接库的使用需要库的开发者提供生成的.lib文件和.dll文件。或者只提供dll文件。
    首先我们必须先注意到DLL内的函数分为两种:
    1)导出函数,可供应用程序调用;
    2) DLL内部函数,只能在 DLL 程序使用,应用程序无法调用它们。
因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。
    Ø 对于DLL的导出,可以采用如下方法:
        #ifdef WLL_EXPORTS
        #define WLL_API__declspec(dllexport)
        #else
        #define WLL_API__declspec(dllimport)
        #endif
    这是导出类的宏定义,将导出类必须加上该宏,才能被导出。
此处的WLL_EXPORTS会出现在 project setting C++ PreProcessor的PreProcessor definition中,这个MACRO表明其要定义一个导出宏。当前库编译时,加了WLL_API的类将被导出,而包含该头文件的其他调用DLL或EXE,由于没有定义WLL_API宏,将申明为导入该类。

Ø 动态库函数的调用,可以采用静态链接的方式 ,主要步骤如下:

1) 包含DLL中导出的头文件。

2) 采用#pragmacomment(lib,"..\\debug\\libTest.lib")导入动态库生成的*.lib头文件。或在projectàsettingsàLinkeràInput的AdditionalDependencies中加入lib文件。

3) 将动态库生成的*.dll文件放到EXE或DLL的同一目录下。

Ø 也可以采用动态加载的方式调用 ,步骤如下:

Another.dll有一个int Add(int x,int y) 函数。则完整的调用过程如下:

typedef int (* FunPtr)(int,int); //定义函数指针

FunPtr funPtr;

Handle handle =LoadLibrary("Another.dll");

funPtr =(FunPtr)GetProcAddress(handle ,"Add");

funPtr(2,3); // 2+3;

FreeLibrary(handle); // 释放载入的动态库

二、 LIB文件

目前以lib后缀的库有两种,一种为静态链接库 (Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称动态库”)的导入库 (Import Libary,以下简称“导入库”)。

静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。

动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。

导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。 

这也是实际上很多开源代码发布的惯用方式:

1、 预编译的开发包:包含一些.dll文件和一些.lib文件。其中这里的.lib就是导入库,而不要错以为是静态库。但是引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。 而.dll则最好放到最后产生的应用程序exe执行文件相同的目录。这样运行时,就会自动调入动态链接库。

2、 用户自己编译:下载的是源代码,按照readme自己编译。生成很可能也是.dll +.lib(导入库)的库文件

3、 如果你只有dll,并且你知道dll中函数的函数原型,那么你可以直接在自己程序中使用LoadLibary调入DLL文件,GetProcAddress获取函数地址,然后调用。

4、vs2008默认并不生成.lib导入库,工程中需要模块定义文件才可生成。方法是:在所建工程上单击鼠标右键,在弹出的右键菜单中选择“添加-->新建项....---->模块定义文件”,在该模块定义文件中写导出函数表,单击确定。然后在所建工程上单击鼠标右键,选择“属性”菜单,在弹出的属性对话框中“链接器-->输入-->模块定义文件”中填写刚才定义的def文件,然后再重新编译即可生成LIB文件。

三、 DLL文件

动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。

动态链接与静态链接的不同之处在于它允许可执行模块(.dll 文件或 .exe 文件)仅包含在运行时定位 DLL 函数的可执行代码所需的信息。在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。


使用动态链接代替静态链接有若干优点。DLL 节省内存,减少交换操作,节省磁盘空间,更易于升级,提供售后支持,提供扩展 MFC 库类的机制,支持多语言程序,并使国际版本的创建轻松完成。

API 就是应用程序编程接口。它是能用来操作组件、应用程序或者操作系统的一组函数。典型的情况下,API 由一个或多个提供某种特殊功能的 DLL 组成。

DLL 是一个文件,其中包含了在 MicrosoftWindows下运行的任何应用程序都可调用的函数。运行时,DLL 中的函数动态地链接到调用它的应用程序中。无论有多少应用程序调用 DLL 中的某个函数,在磁盘上只有一个文件包含该函数,且只在它调入内存时才创建该 DLL。 您听到最多的 API 可能是 WindowsAPI,它包括构成 Windows 操作系统的各种 DLL。每个 Windows 应用程序都直接或间接地与 WindowsAPI 互动。Windows API 保证 Windows 下运行的所有应用程序的行为方式一致。

随着 Windows 操作系统的发展,现已发布了几个版本的 WindowsAPI。Windows 3.1 使用 Win16 API。Microsoft Windows NT、Windows 95 和 Windows 98 平台使用 Microsoft Win32 API。除 Windows API 外,其他一些 API 也已发布。例如,邮件应用程序编程接口 (MAPI) 是一组可用于编写电子邮件应用程序的 DLL。API 传统上是为开发 Windows 应用程序的 C 和 C++ 程序员编写的,但其他的编程语言(包括VBA)也可以调用 DLL 中的函数。因为大部分 DLL 主要是为 C 和 C++ 程序员编写和整理说明的,所以调用 DLL 函数的方法与调用 VBA 函数会有所不同。在使用 API 时必须了解如何给 DLL 函数传递参数。

警告:调用 Windows API 和 其他 DLL 函数可能会给您的应用程序带来不良影响。从自己的代码中直接调用 DLL 函数时,您绕过了 VBA 通常提供的一些安全机制。如果在定义或调用 DLL 函数时出现错误(所有程序员都不可避免),可能会在应用程序中引起应用程序错误(也称为通用性保护错误,或GPF)。最好的解决办法是在运行代码以前保存该项目,并确保了解 DLL 函数调用的原理。

 

四、实例

1、静态链接库

生成lib方法:

 

步骤一,新建项目Win32 Project->Static library,建立一个头文件Lib.h

#pragma once 

#ifdef __cplusplus 

extern "C" { 

#endif 

 

   int add(int a, int b); 

 

#ifdef __cplusplus 

#endif

 

步骤二

新建一个源文件如Lib.cpp

#include "Lib.h" 

int add(int a, int b) 

   return a+b; 

}

 

步骤3:

确定后再编译,这时会在工程所在文件的debug文件夹下产生一个.lib的静态链接库。至此,生成工作完成。

 

 

调用lib方法:

  

调用方法有两种:

第一种:项目设置中引用,在项目的属性中设置。

第二种:在代码中使用 #progma comment(lib,"lib文件名");

这里介绍第一种方法。

右键单击项目,有三个地方需要添加lib库的目录和头文件的目录。

 

步骤一:

右键单击项目—>属性—>配置属性—>链接器—>常规—>附加库目录

在其中填入lib库的目录,也可以是相对或绝对路径。

 

步骤二:

右键单击项目—>属性—>配置属性—>链接器—>输入—>附加依赖项

在其中填入lib库的名称,如:Test.lib

 

步骤三:

新建一个控制台应用程序进行测试

 

#include "stdafx.h"

#include "..\..\Test\Test\Test.h"//注意:这里要include进头文件并且指明路径,或者你可以把头文件直接考到你的工程目录下,并在工程的头文件下把.h文件包含进来,这样只要用 #include “Lib.h”就可以

#include <iostream>

using namespace std;

int main()

{                                                                

    int a = 11, b = 12;

    int c;

    while(1)

    {

        c = add(a, b);

        cout<<c<<endl;

 

    }

    return 0;

 

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值