通过DLL的方式,可以使C++程序在运行时动态的生成一个类对象.测试方法如下:
首先,将C++程序编译链接生成.EXE,这个程序在生成的时候DLL里还没有CAn这个类,因此运行时程序报未定义的错误.但是后来在DLL里加入这个类后,再运行就可以生成这个类对象并调用这个对象的方法.
下面是DLL的.H文件:
#ifdef MYCLASSDLL_EXPORTS
#define MYCLASSDLL_API __declspec(dllexport)
#else
#define MYCLASSDLL_API __declspec(dllimport)
#endif
#ifndef _MYCLASSDLL_H
#define _MYCLASSDLL_H
#include <string>
#include <map>
#include <iostream>
using namespace std;
typedef void* (*CreateClass)(void);
/*@类工厂,通过一个MAP成员来实现类名与类的实例化对象函数的映射
* @向外部提供一个接口函数,通过类名来创建该类对象
* @MAP是静态的,这样可以在程序运行前就可以存在
*/
class MYCLASSDLL_API ClassFactory
{
public:
static void* GetClassByName(string className)
{
map<string,CreateClass>::const_iterator iter;
iter = m_classMap.find(className);
if(iter==m_classMap.end())
return NULL;
else
return iter->second();
}
static void RegistClass(string name,CreateClass method)
{
m_classMap.insert(pair<string,CreateClass>(name,method));
}
private:
static map<string,CreateClass> m_classMap;
};
/*@动态创建类,动态创建的类通过包含该类的一个静态对象
*向类工厂里注册自己的创建对象函数
*/
class MYCLASSDLL_API GenDynamic
{
public:
GenDynamic(string name,CreateClass method)
{
ClassFactory::RegistClass(name,method);
}
};
/*@定义宏,类通过包含该宏,实现动态创建*/
#define DECLARE_RUNTIME(class_name)/
string class_name##Name;/
static GenDynamic* class_name##gd
/*@宏实现,类通过实现该宏,实现动态创建*/
#define IMPLEMENT_RUNTIME(class_name)/
GenDynamic* class_name::class_name##gd/
= new GenDynamic(#class_name,class_name::CreateInstance);
/*@顶层父类*/
class MYCLASSDLL_API CObject
{
private:
DECLARE_RUNTIME(CObject);
public:
CObject()
{
}
static void* CreateInstance()
{
return new CObject;
}
virtual void display()
{
cout<<"CObject display()"<<endl;
}
};
/*@一个子类*/
class MYCLASSDLL_API Csun:public CObject
{
private:
DECLARE_RUNTIME(Csun);
public:
Csun()
{
}
static void* CreateInstance()
{
return new Csun;
}
virtual void display()
{
cout<<"Csun display()"<<endl;
}
};
class MYCLASSDLL_API CMoon:public CObject
{
private:
DECLARE_RUNTIME(CMoon);
public:
CMoon()
{
}
static void* CreateInstance()
{
return new CMoon;
}
virtual void display()
{
cout<<"CMoon display()"<<endl;
}
};
class MYCLASSDLL_API CAn:public CObject
{
private:
DECLARE_RUNTIME(CAn);
public:
CAn()
{
}
static void* CreateInstance()
{
return new CAn;
}
virtual void display()
{
cout<<"CAn display()"<<endl;
}
};
#endif
下面DLL的CPP文件:
// MyClassDll.cpp : 定义 DLL 应用程序的入口点。
//
#include "stdafx.h"
#include "MyClassDll.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
map<string,CreateClass> ClassFactory::m_classMap;
IMPLEMENT_RUNTIME(CObject)
IMPLEMENT_RUNTIME(Csun)
IMPLEMENT_RUNTIME(CMoon)
IMPLEMENT_RUNTIME(CAn)
下面是测试程序的代码:
#include "MyClassDll.h"
#pragma comment(lib,"MyClassDll.lib");
void main()
{
CObject* p = (CObject*)ClassFactory::GetClassByName("CAn");
if(p==NULL)
{
cout<<"未定义"<<endl;
getchar();
return;
}
p->display();
getchar();
}