动态链接库dll的静态加载与动态加载

来源:互联网 发布:软件著作权转让流程 编辑:程序博客网 时间:2024/05/17 01:07

###Date: 2017/9/23

dll的动态加载,又称显式加载,特点有以下几点:

1:灵活,可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存。

2:可以在没有dll时候发现,而不致程序报错。

3:加载程序中有条件才运行的库。

4:热更新,在不停止程序的前提下进行更新。

5:复杂一些,需要显式获得函数地址。

6:dll没有对应的lib文件,此时只能进行动态加载。

7:dll动态加载只需要dll文件就可以了,不需要导入库和头文件。

加载方法:

LoadLibrary

GetProcAddress

FreeLibrary

#include <stdio.h>#include <Windows.h>#pragma comment(lib, "DllLoad.lib")int main(){HINSTANCE h = LoadLibraryA("DllLoad.dll");typedef int(*FunPtr)(int a, int b);//定义函数指针if (h == NULL){FreeLibrary(h);printf("load lib error\n");}else{FunPtr funPtr = (FunPtr)GetProcAddress(h, "add");if (funPtr != NULL){int result = funPtr(8, 3);printf("8 + 3 =%d\n", result);}else{printf("get process error\n");printf("%d", GetLastError());}FreeLibrary(h);}return 0;}


dll静态加载,又称隐式加载,需要把库中所有的函数链接到可执行文件中。

1:简单方便;

2:没有dll时,系统报错;

3:加载运行很久的库;

4:dll必需有相应的lib文件;

5:将整个dll库加载到exe中,占用内存较大,但速度较快。

6:dll静态加载需要dll和lib文件以及.h文件。

在调用OpenCV库时,我们就是采用的dll静态加载的方法进行的。

加载方法:

1、确保有a.dll和a.lib,两个文件都有的话可以用静态加载的方式。
2、在.cpp文件中通过#pragma comment(lib, "a.lib") 加载lib,并包含相应的头文件,就可以使用dll中的函数了

Example:

test.h头文件

#ifndef _TEST_H_#define _TEST_H_#ifdef NEWDLL_EXPORTS  #define MYDLL_API extern "C" __declspec(dllexport)#else#define MYDLL_API extern "C" __declspec(dllimport)#endifMYDLL_API int add(int x, int y);  #endif
test.c

#include <stdio.h>#include "test.h"int add(int x, int y){    return x + y;}

main.c

#include <stdio.h>#include "test.h"#include <Windows.h>//#pragma comment(lib, "DllLoad.lib")int main(){printf("2 + 3 = %d \n", add(2, 3));return 0;}
对test.c进行编译后得到DllLoad.lib和DllLoad.dll,这里通过__declspec(dllexport) 将库中的函数导出。在main.c中可以采用两种方法进行动态库的静态加载。

(1)#pragma comment(lib,"DllLoad.lib")

(2)属性-->配置属性-->链接器-->输入-->附加依赖项中添加DllLoad.lib。

注意此处的.lib文件有一个需要注意的地方是:

  • 静态库——函数和数据被编译进一个二进制文件(扩展名.lib)。在使用静态库的情况下,在编译连接可执行文件时,连接器从库中复制这些函数和数据并把他们和应用程序的其他模块组合起来创建最终的可执行文件(.exe)文件,当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。所以采用静态库链接编译的出来的可执行文件一般比动态库链接编译出来的可执行文件要大很多。
  • 动态库——在使用动态库时,往往提供两个文件:一个引入库(.lib)文件和一个DLL(.dll)文件。虽然引入库的后缀名也是".lib",但是,动态库的引入库文件和静态库文件有着本质的区别。对一个dll来说,引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据,在使用动态库的情况下,在编译连接和执行文件时,只需要连接该DLL的引入库文件,该DLL中的函数代码和数据并不复制到可执行文件中,直到可执行程序运行时,才去加载所需要的DLL,将该DLL映射到进程的地址空间中,然后访问DLL中导出的函数。这时,在发布产品时,除了发布可执行文件以外,同时还要发布该程序将要调用的动态连接库。

参考:http://www.cnblogs.com/pangblog/p/3315627.html

http://blog.163.com/baosongliang@126/blog/static/19493570201561521924773/

阅读全文
0 0