windows 下的静态、动态库

来源:互联网 发布:北京现代软件学院 图片 编辑:程序博客网 时间:2024/04/30 10:49

偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件。然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DLL或者LIB导入到我们的编程中,那么这些libDLL到底是什么呢?下面,偶就细细道来。

 

首先,偶们说第一个静态链接库(Static Libary

偶们用VS2005做一个静态链接库先

打开VS2005,新建à项目(staticCaiàWin32控制台应用程序

新建static_lib.h static_lib.cpp 两个文件,这两个文件的内容如下:

 

 

static_lib.h

 

int add(int x,int y);

int substract(int x , int y);

 

static_lib.cpp

 

#include "static_lib.h"

 

int add(int x,int y)

{

       return x + y;

}

 

int substract(int x,int y)

{

       return x - y;

}

然后编译,生成解决方案,好,这样不出意外会在debug文件夹(与staticCai并列)下生成一个staticCai.lib文件,好了,这个就是我们做好的静态链接库。下面,我们看看怎么用这个静态链接库。我们再新建一个win32控制台程序,新建main.cpp内容如下:

#include <iostream>

#include "static_lib.h"

#pragma comment(lib, "static.lib")

using namespace std ;

 

int main()

{

       cout << add(3 ,4) << endl ;

       cout << substract(5 , 3) << endl ;

       return 0 ;

}

并且将staticCai.libstatic_lib.h这两个文件拷贝到与main.cpp并列的文件夹下。然后,我们编译,链接,执行程序,就会出结果了

#pragma comment(lib, "static.lib")这句和我们在 项目à属性à连接器à添加依赖项 的效果是一样的。至此,怎么做静态链接库以及怎么用静态链接库就搞定了。现在,我们把刚刚拷贝过来的staticCai.lib给删了,我们发现,程序照样执行,但是不能再链接了。所以,我们得出这样的结论:我们再链接的时候需要静态链接库,一旦链接成功,生成了可执行文件,那么,静态链接库就不再需要了。

其次,偶们说第二个动态链接库(dynamic link Libary

同样,我们来做一个动态链接库,和上面的步骤一样,先建工程,只有最后一步稍有不同

然后,新建Dll.cpp文件(这里我们就不做.h文件了),敲入一下内容:

#define  DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;

DLL_API int add(int a,int b)   //实现两个整数相加

{

       return a+b;

}

DLL_API int subtract(int a,int b)   //实现两个整数相减

{

       return a-b;

}

然后,我们编译,生成解决方案,就会在debug文件夹下生成dllCai.dlldllCai.lib。好,至此,动态链接库就做好了,下面我们来看怎么用,新建一个win32控制台程序,新建main.cpp内容如下:

#include <iostream>

using namespace std ;

#pragma comment(lib, "DLL.lib")

extern int add(int a,int b);

extern int subtract(int a,int b);

int main()

{

       cout << add(3 ,4) << endl ;

       cout << subtract(5 , 3) << endl ;

       return 0 ;

}

然后把dllCai.dlldllCai.lib拷贝到与main.cpp并列的目录下。接着,编译,链接,执行,就会看到和上一次一样的结果了。然后,我们把dllCai.lib给删了,程序照样执行,但是不能再链接了,接着,我们把dllCai.dll给删了,程序可以再编译,链接,但是执行的时候就黄了

 

所以,我们说:对于动态链接库,链接的时候需要.lib文件,运行的时候需要.dll文件。

 

至此,静态链接库和动态链接库我们就说完了,我们做一下对比和补充:

1 两个lib文件

我们发现,无论是静态链接库还是动态链接库,最后都有lib文件,那么两者区别是什么呢?其实,两个是完全不一样的东西。staticCai.lib的大小为4KBdllCai.lib的大小为2KB,静态库对应的lib文件叫静态库,动态库对应的lib文件叫导入库。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

2 对于静态链接库,我们在编译和链接的时候已经将所有的代码都导入进来,因此,当生成可执行文件以后,可执行文件包含所有的代码。因此,在可执行文件运行时就不再需要静态库了,这也是为什么我们删掉staticCai.lib程序照样执行;而对于动态链接库,实际上,可执行文件不包含DLL中的内容,只是通过导入库(.lib)知道了相应的地址信息,因此,可执行文件在运行时动态得去加载DLL,这也是为什么我们删掉dllCai.dll后程序就不能执行了。

3 对于DLL,我们是可以不要lib文件的。

如果不要lib文件,我们可以通过函数指针的使用达到我们的目的:

#define  DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;   //注意这里的extern "C" 这里必须加

extern "C" DLL_API int add(int a,int b)   //实现两个整数相加

{

       return a+b;

}

extern "C" DLL_API int subtract(int a,int b)   //实现两个整数相减

{

       return a-b;

}

#include <iostream>

#include <Windows.h>

using namespace std ;

 

typedef int (*func)(int x , int y);  //函数指针

int main()

{

       HINSTANCE hInstance = LoadLibrary("DLL.dll");

       if(hInstance == NULL)

       {

              cout << "SB" << endl ;

              return 0;

       }

       func add = (func)GetProcAddress(hInstance, "add");

       func sub = (func)GetProcAddress(hInstance, "subtract");

       cout << (*add)(3,4) << endl ;

       cout << (*sub)(5,3) << endl ;

}

显然,这种方法没有用lib文件方便,如果为了每次调用一个函数还要自己再弄一个函数指针,多麻烦啊,所以,我们在实际开发中,用的众多的第三方扩展库,别人都是提供的:

.h  文件(类,函数的声明)

.dll 文件(类或函数的实现)

.lib 文件(导入库)

原创粉丝点击