// 第一种方法
//只需要在导出类加上_declspec(dllexport),就可以实现导出。对象空间还是在使用者的模块,dll只提供类中的函数代码,调用者导入库后,
//声明该类的对象,即可调用类中函数
class _declspec(dllexport) CDerived
{
public:
CDerived();
~CDerived();
public:
int InitVideo();
int Play();
private:
int VideoState;
};
//第二种
//这种方式是比较合适的,跟com类似。
//结构是这样的:导出类是一个派生类,派生自一个抽象类,类中都是纯虚函数。使用者需要知道这个抽象类的结构。
//DLL最少只需要提供一个用于获取抽象类对象指针的接口。使用者跟DLL提供者共用一个抽象类的头文件,使用者依赖于DLL的东西很少,
//只需要知道抽象类的接口,以及获取对象指针的导出函数,对象内存空间的申请是在DLL模块中做的,释放也在DLL模块中完成,最后记得要调用释放对象的函数。
//这种方式比较好,通用,产生的DLL没有特定环境限制。借助了C++类的虚函数。一般都是采用这种方式。除了对DLL导出类有好处外,采用接口跟实现分离,
//可以使得工程的结构更清晰,使用者只需要知道接口,而不需要知道实现。
//部分代码:
<pre name="code" class="cpp">//抽象类
class CBase
{
public:
virtual int InitVideo() =0;
virtual int Play() =0;
virtual void Release() =0;
};
__declspec( dllexport ) CBase *GetBaseInstance();
//派生类
#include "Base.h"
class CDerived:public CBase
{
public:
CDerived();
~CDerived();
public:
int InitVideo();
int Play();
void Release();
private:
int VideoState;
};
//派生类简单实现
#include "Derived.h"
__declspec( dllexport ) CBase *GetBaseInstance()
{
return new CDerived;
}
CDerived::CDerived()
{
VideoState=-1;
}
CDerived::~CDerived()
{
}
int CDerived::InitVideo()
{
return 1;
}
int CDerived::Play()
{
return 2;
}
void CDerived::Release()
{
delete this;<span style="font-family: Arial, Helvetica, sans-serif;">}</span>
//调用者引入导出库后,加入Base.h
//调用
CBase * m_pBase=GetBaseInstance();
re=m_pBase->InitVideo();
//DLL导出时 名字改变的问题
C++编译器在生成DLL时,会对导出函数进行改编,并且不同的编译器使用的改编规则不同。此时如果调用放使用C语言的话,就会出现问题。解决方法:在导出函数时,需要加上限定符 extern "C".即: extern "C" _declspec(dllexport)_stdcall是C调用约定,标准调用约定是WINAPI调用约定,