仿MFC實現c++按名動態建立對象之續(瘦身以及解決其在dll中使用的問題)

來源:互聯網
上載者:User

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

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.