日期:2014-05-16  浏览次数:21128 次

windows下的静态库和动态库 -- 简单例子

一 静态库


lib_test.h


int add(int x,int y);
int sub(int x,int y);



lib_test.cpp



#include "lib_test.h"

int add(int x,int y)
{
	return x+y;
}

int sub(int x,int y)
{
	return x-y;
}




main.cpp


#include <iostream>

#include "lib_test.h"

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

using namespace std;


int  main()
{

	cout<<add(1,3)<<endl;
	cout<<sub(1,3)<<endl;

	return 0;

}


运行main.cpp的时候需要上lib_test.h和生成的lib 文件


二 动态库


dll.cpp


#define DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;

DLL_API int add(int a,int b)
{
	return a+b;
}

DLL_API int sub(int a,int b)
{
	return a-b;
}


main.cpp



#include <iostream>

using namespace std;

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

extern int add(int x,int y);
extern int sub(int x,int y);


int main()
{

	cout<<add(1,2)<<endl;
	cout<<sub(2,3)<<endl;
	return 0;

}



运行main.cpp的时候需要.lib文件和.dll文件

我们发现,无论是静态链接库还是动态链接库,最后都有lib文件,那么两者区别是什么呢?其实,两个是完全不一样的东西。静态链接库的lib的大小为4KB,动态链接库的lib的大小为2KB,静态库对应的lib文件叫静态库,动态库对应的lib文件叫导入库。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
2;、;对于静态链接库,我们在编译和链接的时候已经将所有的代码都导入进来,因此,当生成可执行文件以后,可执行文件包含所有的代码。因此,在可执行文件运行时就不再需要静态库了,这也是为什么我们删掉staticCai.lib程序照样执行;而对于动态链接库,实际上,可执行文件不包含DLL中的内容,只是通过导入库(.lib)知道了相应的地址信息,因此,可执行文件在运行时动态得去加载DLL,这也是为什么我们删掉dllCai.dll后程序就不能执行了。
3;、;对于DLL,我们是可以不要lib文件的。
如果不要lib文件,我们可以通过函数指针的使用达到我们的目的:



dll.cpp


#define DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;

extern "C" DLL_API int add(int a,int b)
{
	return a+b;
}

extern "C" DLL_API int sub(int a,int b)
{
	return a-b;
}



main.cpp


#include <iostream>
#include <windows.h>

using namespace std;

typedef int (*func)(int x,int y);

int main()
{

	HINSTANCE hInstance = LoadLibrary("DLLTest.dll");
	if(hInstance==NULL)
	{
		cout<<"hehe"<<endl;
		return 0;
	}

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

	cout<<(*add)(1,2)<<endl;
	cout<<(*sub)(2,3)<<endl;

	return 0;

}


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


一、静态库
静态库是把程序运行时需要使用的函数编译在一个二进制文件中,扩展名为.lib。当程序link时把静态库中的二进制数据和程序其它数据放到一起。程序运行时不在需要lib和dll文件的支持。这样