网上看到的不错的总结,稍加整理,收藏下,方便今后回顾,
1、区别
(1)静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你是否愿意,lib中的指令都会全部包含在最终生成的exe文件中,最终exe执行时不再需要此lib。若使用动态链接库dll,该dll不必被包含在最终生成的exe文件中,exe文件执行时可以“动态”地引用和卸载这个与exe独立的dll文件。
(2)静态链接库中不能在包含其他的动态或者静态链接库,而动态链接库中还可以再包含其他的动态或者静态链接库。
(3)静态链接库的使用,需要库开发者提供生成库的.h文件和.lib文件;动态链接库需要库开发者提供.h文件、.lib文件、.dll文件(静态加载),或只提供.dll文件(动态加载)。
2、加载方式
静态链接库:
在调用程序的.cpp源代码文件中如下:
#include "..\lib.h"
#pragma
comment(lib,"..\\debug\\libTest.lib")
//指定与静态库一起链接
动态链接库:
->静态加载:(需要提供.h、.lib、.dll文件)
在使用的cpp中指定.h 和.lib的路径(或者在vc6.0的Project->Settings...中配置),.dll放到exe同目录下。
#include "..\lib.h"
#pragma
comment(lib,"..\\debug\\libTest.lib")
->动态加载:(只需要提供.dll文件)
因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。但是无法调用Class
method了。
如果要调用Dll中的function,需要经历3个步骤:
Handle
h=LoadLibrary(dllName) --> GetProcAddress(h,functionName)
返回函数指针,通过函指针调用其function-->FreeLibrary(h)
例如:Another.dll有一个int Add(int
x,int y)函数。则完整的调用过程如下:
typedef int (*
FunPtr)(int,int);//定义函数指针
FunPtr funPtr;
Handle
h=LoadLibrary("Another.dll");
funPtr=(FunPtr)GetProcAddress(h,"Add");
funPtr(2,3);//2+3;
FreeLibrary(h);
3、创建方式 (参考网上的)
示例之一:
静态链接库的创建过程:
例如:我们创建一个自定义字符串的类CHironString,
只需要在IDE里面添加class即可,然后program相应函数体
代码如下所示:
SDLL.h文件
------------------------------------------------------------------------
//
HironString.h: interface for the CHironString
class.
//
//////////////////////////////////////////////////////////////////////
#if
!defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_)
#define
AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER
> 1000
class CHironString
{
private:
char* m_data;
public:
char *
GetData();
CHironString(CHironString &other);
int
Length();
CHironString();
CHironString(char *
str);
CHironString& operator=(CHironString &other);
virtual
~CHironString();
};
#endif // !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_)
SDLL.CPP如下:
--------------------------------------------------------------
//
HironString.cpp: implementation of the CHironString
class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HironString.h"
//////////////////////////////////////////////////////////////////////
//
Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHironString::CHironString()
{
m_data=NULL;
}
CHironString::CHironString(char * str)
{
int
len=strlen(str);
m_data=new char[len+1];
strcpy(m_data,str);
}
CHironString::~CHironString()
{
delete m_data;
}
int CHironString::Length()
{
return
strlen(m_data);
}
CHironString::CHironString(CHironString &other)
{
int
len=strlen(other.m_data)+1;
m_data=new
char[len];
strcpy(m_data,other.m_data);
}
CHironString& CHironString::operator =(CHironString
&other)
{
if(this==&other)
return
*this;
if(m_data!=NULL)
delete[] m_data;
int
len=strlen(other.m_data)+1;
m_data=new
char[len];
strcpy(m_data,other.m_data);
return *this;
}
char * CHironString::GetData()
{
return m_data;
}
然后,将程序编译后生成sdll.lib。
客户调用:将CHironString.h和SDLL.lib发布给client,那么客户端就可以调用我们编写的静态链接库了。
示例之二:
动态链接库的创建
首先我们必须先注意到DLL内的函数分为两种:
(1)DLL 导出函数,可供应用程序调用;
(2)DLL 内部函数,只能在 DLL 程序使用,应用程序无法调用它们。
我们还是创建一个自定义的字符串处理类CHironString,不同之处其是一个动态链接库Dll。
动态链接库的export
需要在在相应的头文件中编写相应的MACRO
MyDll.h:自定义了一些类(函数)export
宏(该文件由IDE自动生成)如下
------------------------------------------------------------------
#ifdef
MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define
MYDLL_API
__declspec(dllimport)
#endif
这是导出类的宏定义,将导出类必须加上该宏,才能被导出。
此处的MYDLL_EXPORTS会出现在
project-->settings-->C/C++页面上的 PreProcessor
definition中,这个MACRO表明其要定义一个导出宏
CHironString.h
自定义类头文件
----------------------------------------------------------------
//
HironString.h: interface for the CHironString class.
//
//////////////////////////////////////////////////////////////////////
CHironString.Cpp
------------------------------------------------------------
// HironString.cpp: implementation of the CHironString
class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HironString.h"
//////////////////////////////////////////////////////////////////////
//
Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHironString::CHironString()
{
m_data=NULL;
}
CHironString::CHironString(char * str)
{
int
len=strlen(str);
m_data=new char[len+1];
strcpy(m_data,str);
}
CHironString::~CHironString()
{
delete m_data;
}
int CHironString::Length()
{
return
strlen(m_data);
}
CHironString::CHironString(CHironString &other)
{
int
len=strlen(other.m_data)+1;
m_data=new
char[len];
strcpy(m_data,other.m_data);
}
CHironString& CHironString::operator =(CHironString
&other)
{
if(this==&other)
return
*this;
if(m_data!=NULL)
delete[] m_data;
int
len=strlen(other.m_data)+1;
m_data=new
char[len];
strcpy(m_data,other.m_data);
return *this;
}
char * CHironString::GetData()
{
return m_data;
}
2.如果是动态加载,只需要提供*.dll即可
经过compile之后,会生成MyDll.dll和MyDll.lib文件。
客户端的调用:
1.如果是静态加载,那么需要提供*.lib和*.h,运行时候需提供*.dll
#if
!defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_)
#define
AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER
> 1000
#include "MyDll.h"
class MYDLL_API CHironString //加上MYDLL_API表明此为Export
Class
{
private:
char* m_data;
public:
char *
GetData();
CHironString(CHironString &other);
int
Length();
CHironString();
CHironString(char *
str);
CHironString& operator=(CHironString &other);
virtual
~CHironString();
};
#endif // !defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_)
原文:http://www.cnblogs.com/weiquxiong/p/3547766.html