对dll 接口用单例模式来封装 (例子)。

来源:互联网 发布:金融类软件如何推广 编辑:程序博客网 时间:2024/06/07 00:31

/*
 * author: hjjdebug
 * date : 2011
 * 对共享内存接口用单例模式封装
 * 先介绍一下单例模式的要点。
 * 1.     所谓单例模式,就是只有一个实例。所以你不能随便声明一个单例对象,也就是说单例对象
 *         只会走一次构造函数。所以实现上把构造函数设置成私有函数,使外部声明对象变为非法。
 *
 * 2.     那么怎样得到单例模式的实例句柄呢?
 *        用类静态函数GetInstance()
 * 举例:下面是我的一个使用例。
 * 该例子功能为,父进程创建了一个sharemem, 子进程使用这个sharemem.
 * 子进程使用sharemem 接口被写成了一个DLL 文件, 本来在子进程中,可以直接使用DLL 的导出函数
 * 但为了进一步简化接口,将这些dll 导出函数又封装到一个单例类。 因为这个接口对象有且只能有
 * 一个实例。
 * 下面代码为子进程使用共享内存的例子。
 */
////////////////////////////////////////////////////////////////////////////////
// 获取实例句柄,调用接口函数
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "ShareMemDll.h"

using namespace std;

//main
int main(int argc, char* argv[])
{
    SingletonDll *pSingletonDll = SingletonDll::GetInstance();
    if(pSingletonDll)
    {
        BOOL ret=pSingletonDll->IsShareMemoryOK();
        printf("ret is %d",ret);
    }
    system("pause");
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
// 下面为 ShareMemDll.h 头文件
// 用来定义ShareMem 的结构。 上面为状态区,下面为信息区
// 同时,封装一个单例类,把接口函数地址用成员变量来保存。
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <windows.h>
#include <string>
using namespace std;

struct TaskStatus{
    int taskId;        //任务id  服务器端传下来的。
    float progress; //任务进度 0 - 1    input
    BOOL isFinish;//是否完成            input
    BOOL isFailed;//是否失败            input
    BOOL forseStop;    //强制中止            output
    // int returnValue;//返回值
};
struct ShareMem{
    TaskStatus status;    //任务状态
    wchar_t info[16*1024]; //共享信息区
};


// wstring _declspec(dllexport)  GetParams();
typedef wstring(* F_GetParams)(void);
typedef BOOL  (*F_IsStop)(void);
typedef void  (* F_SetProgress)( float progress );
typedef void (* F_TaskEnd)(BOOL isSuccess, wstring returnValue);
typedef BOOL (*F_IsShareMemoryOK)(void);
typedef BOOL (*F_ClearTaskParam)(void);


//单例类的Dll C++实现
class SingletonDll
{
private:
    SingletonDll();//注意:构造方法私有
    static SingletonDll instance;//惟一实例
public:
    HMODULE hModule;
    virtual ~SingletonDll();
    F_IsStop IsStop;
    F_SetProgress SetProgress;
    F_TaskEnd TaskEnd;
    F_GetParams GetParas;
    F_IsShareMemoryOK IsShareMemoryOK;
    F_ClearTaskParam ClearTaskParam;
    static SingletonDll GetInstance();//工厂方法(用来获得实例)
};
////////////////////////////////////////////////////////////////////////////////
// 单例接口类的实现。获取了各个接口的地址。
// 演示了当不得不采用c++导出时,导出函数名称是很长的
////////////////////////////////////////////////////////////////////////////////
/*
author: hjj
date: 2010
description: share mem dll 的单例封装调用
...
*/
#include "ShareMemDll.h"

//初始化静态成员
SingletonDll SingletonDll::instance;

//构造方法实现
SingletonDll::SingletonDll()
{
    hModule=LoadLibrary(L"ShareMemDll.dll");
    if(!hModule)
    {
        printf("ShareMemDll not loaded/n");
        return;
    }
    IsShareMemoryOK=(F_IsShareMemoryOK)GetProcAddress(hModule,"IsShareMemoryOK");
    SetProgress=(F_SetProgress)GetProcAddress(hModule,"SetProgress");
    IsStop=(F_IsStop)GetProcAddress(hModule,"IsStop");
    TaskEnd=(F_TaskEnd)GetProcAddress(hModule,"TaskEnd");
    ClearTaskParam=(F_ClearTaskParam)GetProcAddress(hModule,"ClearTaskParam");

    GetParas=(F_GetParams)GetProcAddress(hModule,"?GetParams@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ");
    if(!IsShareMemoryOK||!SetProgress||!IsStop||!TaskEnd||!ClearTaskParam||!GetParas)
    {
        printf("ShareMemory Dll Maybe corrupted/n");
        FreeLibrary(hModule);    // 当接口不匹配时, 设置hModule 为空
        hModule = NULL;
    }
}

SingletonDll::~SingletonDll()
{
    if(hModule)
    {
        FreeLibrary(hModule); //此处的hModule, 就是instance 所指的module
        hModule = NULL;
    }
}

//类静态成员函数
SingletonDll SingletonDll::GetInstance()
{
    return instance;   //instance 是一个静态成员对象,返回为唯一值
}
//--------------------------------------------------------------------------------

原创粉丝点击