统一Windows 内置与外置,插件的一种设计方式

884阅读 0评论2010-10-27 pagx
分类:WINDOWS

目的: 
1、插件可以编译进主程序的可执行文件也可以单独编译成动态链接库DLL。
2、源代码不需要修改,只需要在编译时定义不同的宏作为编译器的编译参数。

一个例子: (gcc -DDSPLUGIN )

#include <stdio.h>
#include "plugin.h"

static int GetDataTransferState(void)
{
    return 0;
}

static int DataTransferInit(void)
{
    DSP_SYMBOL(GetDataTransferState);
    return 0;
}

static int DataTransferStart(void)
{
    return 0;
}

static int DataTransferStop(void)
{
    return 0;
}

DSCLIENT_PLUGIN(DataTransfer, DataTransferInit, 0, DataTransferStart, DataTransferStop);


加载插件: (gcc -DDSCLIENT )

#include <stdio.h>
#include <windows.h>

int LoadPlugin(const char * name, PDSPlugin pplugin)
{
    char buf[1024];
    HINSTANCE hModule = GetModuleHandle(NULL);
    sprintf(buf, "DSGetPlugin_%s\n", name);
    pfunc = GetProcAddress(hModule, buf);
    if (pfunc != NULL) {
        pplugin->module = NULL;
        return pfunc(pplugin);
    }

    foreach (file in plugindir) {
        hModule = LoadLibrary(file);
        get_plugin_name = GetProcAddress(hModule, "DSP_GetPluginName");
        if (strcmp(name, get_plugin_name()) == 0) {
            pplugin->init = GetProcAddress(hModule, "DSP_Initialize");
            pplugin->clean = GetProcAddress(hModule, "DSP_Cleanup");
            pplugin->start = GetProcAddress(hModule, "DSP_Start");
            pplugin->stop = GetProcAddress(hModule, "DSP_Stop");

            pplugin->module = hModule;

            return 0;
        }
        FreeLibrary(hModule);
    }
}


头文件:

#ifndef _PLUGIN_H_
#define _PLUGIN_H_

#define DSP_SYMBOL(name) DSSymbolAdd(#name, name)
#define DSP_EXPORT __declspec(dllexport)
void * DSSymbolQuery(const char * name);
int DSSymbolAdd(const char * name, void * symbol);

#ifdef DSCLIENT
#define DSCLIENT_PLUGIN(name, init, clean, start, stop) \
int DSGetPlugin_##name(PDSPlugin pplugin) \
{ \
    pplugin->init = init; \
    pplugin->clean = clean; \
    pplugin->start = start; \
    pplugin->start = stop; \
    return 0; \
}
#endif

#ifdef DSPLUGIN
#define DSCLIENT_PLUGIN(name, init, clean, start, stop) \
DSP_EXPORT const char * DSP_GetPluginName(void) { return #name; } \
DSP_EXPORT int DSP_Initialize(void) { return init(); } \
DSP_EXPORT int DSP_Cleanup(void) { return clean(); } \
DSP_EXPORT int DSP_Start(void) { return start(); } \
DSP_EXPORT int DSP_Stop(void) { return stop(); }
#endif

#ifndef DSCLIENT_PLUGIN
#error "DSCLIENT_PLUGIN must defined!"
#endif

#endif


上一篇:Windows 下个关机代码
下一篇:针对TCP时间戳PAWS漏洞的代码。