动态链接库是编绎好的二进制文件与exe文件类似,但它不能单独运行。它是一个独立的模块,也包含了代码、数据或资源,能被其它程序共享。多个程序调用动态链接库里的同一个函数时,理论上该函数在内存中只存在一份拷贝。

静态链接库编绎器在编绎时会将函数和过程都编绎到可执行文件中,这样会造成可执行文件很大。多个程序调用静态链接库时,每个程序都拥有该库里函数的拷贝,若这些程序同时运行则内存中会拥有该库中函数的多份拷贝。

动态链接库的好处:

1 有利于程序的模块化。

2 共享代码、数据、资源。

3 程序在运行时调入代码运行,而不是将其编绎到可执行文件中,节省了内存。动态链接库调用方式:

1 隐式链接,即使不调用库里面的函数,启动时也会加载库文件。需要把产生动态链接库时产生的.lib文件加入到应用程序工程中,该文件包含了每一个dll导出函数的符号名和可选的标识号,但是并不含有实际的代码。lib文件作为dll的替代文件被编译到应用程序项目中。

2 显式链接,是指在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态连接库调进来,动态连接库的文件名即是上面两个函数的参数,再用GetProcAddress()获取想要引入的函数。用完时调用FreeLibrary对动态库进行卸载。频繁的调用会牺牲一部分时间。

以下用一个例子来说明这两种调用。

1 在VC6.0下新建一个WIN32 Dynamic Library工程,工程名为mydll1,然后在这个工程中建立mydll.h , mydll.cpp这两个文件,文件的类容分别为:

mydll.h

#ifndef MYDLL_H

#define MYDLL_H

#ifdef API_DLL

#else

#define API_DLL _declspec(dllimport) //_declspec(dllimport)声明函数是导入函数,表示此//函数是从外部导入进来了函数,一般在调用dll的程序中这样声明。此处这个头文件会被//调用程序所使用。

#endif

API_DLL int add(int a,int b);

API_DLL int sub(int a,int b);

#endif

mydll.cpp

#include “mydll.h”

#define API_DLL _declspec(dllexport) //_declspec(dllexport)声明函数是导出函数,表示此//函数是导出给外部程序使用的。

int add(int a,int b)

{

return a+b;

}

int sub(int a,int b)

{

return a-b;

}

编绎、链接后,在工程文件下可以发现mydll.dll, mydll.lib这两个文件。这两个文件在以后的隐式链接中会用到。

2 在VC6.0下再建一个WIN32 Dynamic Library工程,工程名为dll2,然后在这个工程中建立dll2.cpp这两个文件,文件的类容为:

_declspec(dllexport) int max(int a,int b)

{

return a>b?a:b;

}

_declspec(dllexport) int min(int a,int b)

{

return a<b?a:b;

}

编绎链接后,可以在工程文件下发现dll2.dll这个文件。这个文件在接下来的工程中会被用来显示链接。

3 在VC6.0下再建一个WIN32 Consol Application工程,工程名为calldll然后在这个工程中建立calldll.cpp文件,文件的类容为:

calldll.cpp

#include <stdio.h>

#include “windows.h”

#include “mydll.h”

#pragma comment(lib,”mydll.lib”)//这行可以不要,如果不要这行的话需要在//Project---setting---link---object/library中加入mydll.lib

void main()

{

//下面这8行是显示加载dll2.dll中的函数

HINSTANCE hint;

hint=LoadLibrary(“dll2.dll”);              //加载dll2.dll

typedef int (*FUN)(int a,int b);            // 自定义函数指针

FUN MAX=(FUN)GetProcAddress(hint,“max”);// 获取dll2.dll中的max函数句柄

FUN MIN=(FUN)GetProcAddress(hint,“min”);// 获取dll2.dll中的min函数句柄

printf(“%d \n”,MAX(1,2));

printf(“%d \n”,MIN(1,2));

FreeLibrary(hint);       //释放动态链接库dll2.dll

//下面两行是调用mydll中的add和sub函数。

printf(“%d \n”,add(1,2));

printf(“%d \n”,sub(1,2));

}

在完成了以上三步后,还不能通过编绎第三个工程,要想通过编绎,先把第一个工程也就是mydll这个工程中的mydll.dll,mydll.lib,mydll.h这三个文件拷贝到calldll工程文件中也就是与calldll中的.cpp文件在同一目录,然后把dll2这个文件中的dll2.dll也拷到calldll工程中,这下编绎、链接calldll这个工程,如果没有错误的话。那么就可以直接运行了,运行过后会看到所期望的结果。

这里因为dll2.dll是显示调用的所以只拷贝dll2.dll这个文件到calldll这个工程中就行了。

而mydll.dll是隐式调用的所以需要将mydll.lib也放到工程中去。

编写此文参考了以下这个地址的内容。

http://blog.csdn.net/zieckey/article/details/1418653

转载于:https://blog.51cto.com/w2qianjin/719249

动态链接库的编写与调用相关推荐

  1. VS2019 - 动态库的编写和调用

    VS2019 - 动态库的编写和调用 完善自己知识体系的一些内容: 用C++编写的DLL(动态链接库)中,导出类的接口封装方法总结 详解dll的封装,以及三种调用方法(将±×÷封装为例) 1 VS20 ...

  2. 视频教程-PHP扩展模块开发之DLL编写与调用-PHP

    PHP扩展模块开发之DLL编写与调用 云知梦创始人,国际架构师,11年互联网培训和开发经验,曾在港电讯盈科.北大青鸟集团.远大教育.北京易第优教育等公司任职曾获得美国红帽RHCA构架师和RHCDS数据 ...

  3. 动态链接库的建立与调用

    一:实验目的 (1)理解动态链接库的实现原理. (2)掌握Windows系统动态链接库的建立方法. (3)掌握Windows环境下动态链接库的调用方法. 二:实验准备知识:动态链接库介绍 ​ 动态链接 ...

  4. WebService的编写与调用

    WebService的编写与调用 编写:启动VS08,选择模版.c#语言,默认有"Hello World"方法,自己编写的webservice要注意的是必须加上[Web Metho ...

  5. Delphi中高级DLL的编写和调用

            根据Delphi提供的有关 DLL编写和调用的帮助信息,你可以很快完成一般的 DLL编写和调用的 应用程序.本文介绍的主题是如何编写和调用能够传递各种参数(包括对象实例)的 DLL.例 ...

  6. CUDA C中核函数(kernel)的编写及调用

    CUDA C程序中最重要的部分就是核函数(kernel)的编写和调用.在此,我们以HelloWorld程序为例,分别讲述kernel函数的编写和调用. 1.kernel函数的编写: __global_ ...

  7. python语言+selenium自动化,编写脚本调用Chrome、Firefox浏览器打开百度网站

    python语言+selenium自动化,编写脚本调用Chrome.Firefox浏览器打开百度网站 目标:初始化一个webdriver实例对象driver,通过webdriver.Chrome()和 ...

  8. EffectiveC++详解:条款05-了解C++默默编写并调用哪些函数

    文章目录 条款05-了解C++默默编写并调用哪些函数 当我们写了一个空类,意味着什么 编译器什么时候拒绝生成拷贝赋值运算符 总结 @Author:CSU张扬 @Email:csuzhangyang@g ...

  9. Effective C++条款05:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)

    Effective C++条款05:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls) 条款05:了解C++默默编写 ...

最新文章

  1. AOSP 设置编译输出目录
  2. KVM 实现机制---(很經典)
  3. Netty源码分析第6章(解码器)----第4节: 分隔符解码器
  4. 解决plt.savefig存的图是空白的
  5. zipline-benchmarks.py文件改写
  6. 超全超详细的HTTP状态码大全
  7. Windows下VC++显示UTF-8编码中文
  8. 烟花代码,予心上人最璀璨烟花—— 附源码与成品(HTML+CSS+JS)
  9. QT实现USB热插拔监控
  10. Excel如何快速在指定字符后面插入文本
  11. UOJ449. 【集训队作业2018】喂鸽子 [概率期望,min-max容斥,生成函数]
  12. 10019---mybatis的缓存机制(一级缓存二级缓存和刷新缓存)
  13. [Canvas系列]Canvas简单线条绘制_02
  14. 模拟登录qq网页版方法
  15. 计算机基础作业1,学习平台-北京大学16春计算机基础与应用作业1答案-成人高等教育_成人本科教育报名_远程网络教育学院-江苏学历网报名服务中心...
  16. 《CASCADED TIME + TIME-FREQUENCY UNET FOR SPEECH ENHANCEMENT:JOINTLY ADDRESSING CLIPPING》论文阅读
  17. Http协议之301,302和307
  18. 周期循环图像边界算法
  19. 程序员常用mysql命令
  20. RFI/RFP/RFQ

热门文章

  1. BZOJ 1666 USACO 2006 Oct. 奶牛的数字游戏
  2. 人人都是产品经理读书笔记(四)
  3. 如何有效防止DEDE织梦系统被挂木马安全设置(仅供参考)
  4. css:hover选择器
  5. 用unescape反编码得出汉字
  6. IromPython .Net 的简介和第一个例子
  7. 关于Go语言在服务端做Restful接口和socket通信
  8. Gabor滤波小结整理
  9. 平凡的世界,有感而发
  10. 聚类--K均值算法:自主实现与sklearn.cluster.KMeans调用