动态链接库dll的几种制作和使用方法比较



(个人总结,可能有错误,待修改)
方法 优点/缺点
1. 加载时动态链接(Load-Time Dynamic Linking) 使用简单,dll中可以导出函数、变量、类。
2. 运行时动态链接(Run-Time Dynamic Linking) 运行时才加载、可以显式卸载,dll替换方便,只能导出函数, 使用一定的技巧后可以导出类。
3.COM方法
需要注册。


各个方法示例
1. 加载时动态链接(Load-Time Dynamic Linking)

2. 运行时动态链接(Run-Time Dynamic Linking)

3. 运行时动态链接导出类
    1)   把所有需要用到的接口收集起来,写一个虚的基类,即所有成员函数都声明成虚函数,且该接口类不带任何数据成员  
    2)   让需要导出的类从该接口类派生,不必导出了。  
    3)   导出一个全局的C接口创建该类,即返回接口类的指针  
//dll项目中的:
//文件ivcscomm.h
struct IVcscomm
{
 virtual int Testa(int a)=0;//必须加上=0
};

//文件vcomm.h

#include "ivcscomm.h"

class Vcomm : public IVcscomm
{
public:
 Vcomm(void);
public:
 ~Vcomm(void);
public:
 int Testa(int a);

};


//文件vcomm.cpp

#include "Vcomm.h"

Vcomm::Vcomm(void)
{
}

Vcomm::~Vcomm(void)
{
}

int Vcomm::Testa(int a)
{
 return 5*a;
}

#define DllExport   __declspec( dllexport )
extern "C" DllExport IVcscomm* createIVcscomm()
{
 return new Vcomm();
}


//使用dll的程序:
//在头文件中
#include "IVcscomm.h"

 typedef IVcscomm* (* LPFNDLLFUNC2)();

//在cpp中使用
 HINSTANCE hDLL = LoadLibrary(_T("Dlla")); // Handle to DLL
 if (hDLL != NULL)
 {
  Log(_T("hDLL != NULL"));
  LPFNDLLFUNC2 lpfnDllFunc2 = (LPFNDLLFUNC2)GetProcAddress(hDLL, "createIVcscomm");
  if (!lpfnDllFunc2)
  {
   // handle the error
   FreeLibrary(hDLL);
   Log(_T("!lpfnDllFunc2"));
   return;
  }
  else
  {
   // call the function
   IVcscomm* pcmm = lpfnDllFunc2();
   int uReturnVal = pcmm->Testa(5);
   CString ln;
   ln.Format(_T("uReturnVal==%d"), uReturnVal);
   Log(ln);
   FreeLibrary(hDLL);
   return;
  }
 }


4. COM方法