您的位置:首页 > 编程语言 > C语言/C++

仿MFC实现c++按名动态创建对象之续(瘦身以及解决其在dll中使用的问题)

2008-10-24 10:33 1126 查看
      之前仿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;
}

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dll mfc c++ class api null
相关文章推荐