之前仿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;
}