您的位置:首页 > 其它

[开源世界]增强版的动态链接库接口导出框架

2013-10-22 10:06 141 查看
参考:
从自动导出动态链接库接口看C++的缺点

更新内容:

1.封装了gDllImportList变量,删除了DllImportAttribute.cpp文件。

2.封装了User32类的全局变量,删除了User32.cpp文件。

更新后的框架只需要一个 DllImportAttribute.h文件,导出函数的文件也只需要一个,减少了文件数量。

#pragma once

#include <Windows.h>

#include <list>
using namespace std;

/*
* DllImportAttribute
* 定义加载和卸载动态链接库的接口
*/

class DllImportAttribute
{
public:
// 加载动态链接库
virtual BOOL Init() = 0;

// 卸载动态链接库
virtual BOOL Uninit() = 0;
};

/*
* DllImportList
* 封装gDllImportList(全局)变量,避免使用cpp文件
*/

class DllImportList
{
protected:
static DllImportList* m_pInstance;

public:
static DllImportList* CreateInstance()
{
if (m_pInstance == NULL)
{
m_pInstance = new DllImportList();
}
return m_pInstance;
}

static void DeleteInstance()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
}

list<DllImportAttribute*> gDllImportList;
};

DllImportList* DllImportList::m_pInstance = NULL;

// 加载所有库,用在程序初始化的地方
inline BOOL DllImportInit()
{
BOOL bSuccess = TRUE;

auto& list = DllImportList::CreateInstance()->gDllImportList;

for (auto iter = list.begin(); iter != list.end(); iter++)
{
bSuccess &= (*iter)->Init();
}

return bSuccess;
}

// 卸载所有库,用在程序退出释放资源的地方
inline BOOL DllImportUninit()
{
BOOL bSuccess = TRUE;

auto& list = DllImportList::CreateInstance()->gDllImportList;

for (auto iter = list.begin(); iter != list.end(); iter++)
{
bSuccess &= (*iter)->Uninit();
}

// 别放了删除DllImportList实例
DllImportList::DeleteInstance();

return bSuccess;
}

/*
* DLLIMPORTCLASSBEGIN
* 定义CLASS##Dll类的前半部分,主要是库加载、卸载以及封装自身实例(避免使用Cpp文件)
* m_nOffPtr :指示变量的位置
*/

#define DLLIMPORTCLASSBEGIN(CLASS, DLLPATH) class CLASS##Dll : public DllImportAttribute    \
{   \
protected:  \
HMODULE  m_hModule; \
public: \
CLASS##Dll() : m_hModule(NULL) {    \
DllImportList::CreateInstance()->gDllImportList.push_back(this); \
}   \
virtual BOOL Init() {   \
m_hModule = LoadLibraryA(DLLPATH);  \
return (m_hModule != NULL); \
}   \
virtual BOOL Uninit() { \
BOOL bFreeSuccess = FreeLibrary(m_hModule); \
CLASS##Dll::DeleteInstance();   \
return bFreeSuccess;    \
}   \
protected:  \
static CLASS##Dll* m_pInstance; \
public: \
static CLASS##Dll* CreateInstance() \
{   \
if (m_pInstance == NULL)    \
{   \
m_pInstance = new CLASS##Dll(); \
memset((BYTE*)m_pInstance + offsetof(CLASS##Dll, m_nOffPtr), 0, \
sizeof(CLASS##Dll) - offsetof(CLASS##Dll, m_nOffPtr));  \
}   \
return m_pInstance; \
}   \
static void DeleteInstance()    \
{   \
if (m_pInstance != NULL)    \
{   \
delete m_pInstance; \
m_pInstance = NULL; \
}   \
}   \
protected:  \
int m_nOffPtr;  \

/*
* FUNCTIONENTRY
*/

#define FUNCTIONENTRY(ENTRYTYPE, ENTRYPOINT)    protected:  \
typedef ENTRYTYPE;  \
ENTRYPOINT ENTRYPOINT##Ptr; \
public: \
ENTRYPOINT ENTRYPOINT##Func()   \
{   \
if (ENTRYPOINT##Ptr == NULL)    \
{   \
ENTRYPOINT##Ptr = (ENTRYPOINT)GetProcAddress(m_hModule, #ENTRYPOINT);   \
}   \
return ENTRYPOINT##Ptr; \
}   \

/*
* DLLIMPORTCLASSEND
*/

#define DLLIMPORTCLASSEND(CLASS) }; \
CLASS##Dll* CLASS##Dll::m_pInstance = CLASS##Dll::CreateInstance(); \

/*
* DLLIMPORTCALL
*/

#define DLLIMPORTCALL(CLASS, ENTRYPOINT)    CLASS##Dll::CreateInstance()->ENTRYPOINT##Func()

#pragma once

#include "DllImportAttribute.h"

DLLIMPORTCLASSBEGIN(User32, "User32.dll")
FUNCTIONENTRY(int(WINAPI *MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT), MessageBoxA)
DLLIMPORTCLASSEND(User32)

DllImportInit();

DLLIMPORTCALL(User32, MessageBoxA)(NULL, "ad", "ad", MB_OK);

DllImportUninit();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: