之前仿MFC实现了动态类型识别以及动态创建的功能,不过由于我只需要动态创建的功能,因为c++在MFC弄出CRuntimeClass之后以及加上了自己的RTTI机制,所以想对之前的版本的进行一下瘦身,去掉不必要的与动态类型识别相关的代码。
另外,这一动态创建的功能想能用到的dll中,单个dll使用该功能没有异常现象,可多个dll使用问题就出来了,追根究底,问题出在静态变量的初始化问题上,使用LoadLibarary一个个加载用到的dll,dll中的类的相关静态变量能够得以初始化,而以隐式调用的方法使用这些dll,则仅仅只有一个dll里面的类的相关静态变量被初始化。没有找出其中的原因所在,姑且在使用时将要使用的dll先都LoadLibrary一遍。
代码:
////////////////////////////////////////////////实现动态创建的Dll的代码
///////////////////dll.h
#ifdef DLL_EXPORT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
//////////////////DynamicCreate.h
#ifndef DYNAMICCREATE_H
#define DYNAMICCREATE_H
//#define DLL_EXPORT
#include "dll.h"
#include <iostream>
struct DLL_API DynamicCreateSt
{
char *classname;
void* (*pCreateFn)();
void* CreateObject();
static DynamicCreateSt* LoadByName(std::string classname);
static DynamicCreateSt *pFirstClass;
DynamicCreateSt *pNextClass;
};
struct DLL_API Class_List
{
Class_List(DynamicCreateSt* pNewClass);
};
#define Declare_DynCreate(classname) /
public: /
static DynamicCreateSt class##classname; /
static void* CreateObject(); /
#define Implement_DynCreate(classname) /
void* classname::CreateObject() /
{ return new classname; } /
static char lpsz##classname[]=#classname; /
DynamicCreateSt classname::class##classname= /
{ lpsz##classname,classname::CreateObject,NULL}; /
static Class_List _init_##classname(&classname::class##classname); /
#endif
////////////////////DynamicCreate.cpp
#define DLL_EXPORT
#include "DynamicCreate.h"
DynamicCreateSt* DynamicCreateSt::pFirstClass=NULL;
Class_List::Class_List(DynamicCreateSt* pNewClass)
{
pNewClass->pNextClass=DynamicCreateSt::pFirstClass;
DynamicCreateSt::pFirstClass=pNewClass;
}
void* DynamicCreateSt::CreateObject()
{
if (pCreateFn == NULL)
{
return NULL;
}
void* pObject = NULL;
pObject = (*pCreateFn)();
return pObject;
}
DynamicCreateSt* DynamicCreateSt::LoadByName(std::string classname)
{
DynamicCreateSt* pClass;
for (pClass = pFirstClass; pClass != NULL; pClass = pClass->pNextClass)
{
if (strcmp(classname.c_str(), pClass->classname) == 0)
return pClass;
}
return NULL;
}
////////////////////////////////////////////////////////////用来测试的dll1的代码,需要隐式调用上述的dll
////////////////////dll1_A.h
#include "DynamicCreate.h"
class DLL_API dll1_A
{
Declare_DynCreate(dll1_A)
public:
dll1_A(void);
public:
~dll1_A(void);
public:
virtual void dosth()
{
std::cout<<"dll1_A/n";
}
};
//////////////////dll1_A.cpp
#define DLL_EXPORT
#include "dll1_A.h"
Implement_DynCreate(dll1_A)
dll1_A::dll1_A(void)
{
}
dll1_A::~dll1_A(void)
{
}
/////////////////dll1_AC.h
#include "dll1_a.h"
class DLL_API dll1_AC :
public dll1_A
{
Declare_DynCreate(dll1_AC)
public:
dll1_AC(void);
public:
~dll1_AC(void);
public:
void dosth()
{
std::cout<<"dll1_AC/n";
}
};
/////////////////dll1_AC.cpp
#define DLL_EXPORT
#include "dll1_AC.h"
Implement_DynCreate(dll1_AC)
dll1_AC::dll1_AC(void)
{
}
dll1_AC::~dll1_AC(void)
{
}
////////////////////////////////////////////////////////////用来测试的dll2的代码,需要隐式调用上述的dll
////////////////////dll2_A.h
#include "DynamicCreate.h"
class DLL_API dll2_A
{
Declare_DynCreate(dll2_A)
public:
dll2_A(void);
public:
~dll2_A(void);
public:
virtual void dosth()
{
std::cout<<"dll2_A/n";
}
};
//////////////////dll2_A.cpp
#define DLL_EXPORT
#include "dll2_A.h"
Implement_DynCreate(dll2_A)
dll2_A::dll2_A(void)
{
}
dll2_A::~dll2_A(void)
{
}
/////////////////dll2_AC.h
#include "dll2_a.h"
class DLL_API dll2_AC :
public dll2_A
{
Declare_DynCreate(dll2_AC)
public:
dll2_AC(void);
public:
~dll2_AC(void);
public:
void dosth()
{
std::cout<<"dll2_AC/n";
}
};
/////////////////dll2_AC.cpp
#define DLL_EXPORT
#include "dll2_AC.h"
Implement_DynCreate(dll2_AC)
dll2_AC::dll2_AC(void)
{
}
dll2_AC::~dll2_AC(void)
{
}
//////////////////////////////////////////////////////////////////////////测试程序代码
#include "dll1_A.h"
#include "dll2_A.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
LoadLibrary(_T("dll1.dll"));
LoadLibrary(_T("dll2.dll"));
DynamicCreateSt* prc;
for(prc=DynamicCreateSt::pFirstClass;prc!=NULL;prc=prc->pNextClass)
{
std::cout<<prc->classname<<"/n";
}
DynamicCreateSt* dcs=DynamicCreateSt::LoadByName("dll1_A");
dll1_A* pa=(dll1_A*)dcs->CreateObject();
pa->dosth();
dcs=DynamicCreateSt::LoadByName("dll2_AC");
dll2_A* pb=(dll2_A*)dcs->CreateObject();
pb->dosth();
getchar();
return 0;
}