DLL 导出C++ 类

// 第一种方法

//只需要在导出类加上_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调用约定,  
 
 
 

你可能感兴趣的:(dll)