Skip to content
Zhang Yungui edited this page Dec 19, 2011 · 6 revisions

如何加载插件

详细例子见 source/example/consoledemo/main.cpp,在此文件中有五种加载方式。

1、同时使用多个插件的简单加载方法

#include <portability/x3port.h>     // 相当于#include<windows.h>
#include <nonplugin/useplugins.h>   // 包含辅助加载类,一个工程内只能包含一次

void yourFunction()
{
    // 多个插件文件名,以NULL结尾
    const char* plugins[] = {
        "x3manager.pln", "plsimple.pln", "observerex.pln", NULL
    };
    // 自动加载和卸载插件,插件在程序文件的plugins子目录下
    x3::AutoLoadPlugins autoload(plugins, "plugins");

    // 可以使用接口了。。。
}

2、仅使用一个插件的简单加载方法

#include <portability/x3port.h>     // 相当于#include<windows.h>

// 插件在程序文件的plugins子目录下,如果不定义则插件与程序同目录
// 注意末尾有目录分隔符,在包含useplugin.h前定义,如果不定义则为默认的空串
#define PLUGIN_PATH  "plugins/"

// 要使用的插件文件名,没有目录和后缀名(.pln)
#define PLUGIN_NAME  "plsimple"

// 包含辅助加载类,一个工程内只能包含一次
#include <nonplugin/useplugin.h>

void yourFunction()
{
    // 可以使用接口了。。。
}

3、遍历目录下的所有插件

#include <portability/portimpl.h>   // 兼容实现,一个工程内只能包含一次
#include <utilfunc/scanfiles.h>     // 遍历目录的辅助函数

HMODULE modules[10] = { NULL };
int count = 0;

// scanfiles的回调函数
bool filter(const char* filename, const char* ext)
{
    if (_stricmp(ext, ".pln") == 0)                 // 是插件后缀名
    {
        modules[count] = x3LoadLibrary(filename);   // 加载插件
        if (modules[count])
            count++;
    }
    return count < 10;
}

int yourFunction()
{
    char path[MAX_PATH];

    // 形成绝对路径: <exepath>\plugins
    GetModuleFileNameA(NULL, path, MAX_PATH);
    PathRemoveFileSpecA(path);
    PathAppendA(path, "plugins");

    // 遍历此目录,加载其中的插件文件
    x3::scanfiles(filter, path, true);

    // 可以使用接口了
    test();

    // 卸载所有插件,后加载的先卸载
    while (--count >= 0)
    {
        x3FreeLibrary(modules[count]);
    }
}

// 由于没有使用useplugins.h、useplugin.h、pluginimpl.h,就自己实现createObject
namespace x3 {
class IObject;
bool createObject(const char* clsid, long iid, IObject** p)
{
    typedef bool (*F)(const char*, long, IObject**);
    F f = (F)GetProcAddress(modules[0], "x3CreateObject");
    return f && f(clsid, iid, p);
}
} // x3

4、其他内容

此处不介绍另外两种不常用的加载方式(原生加载方式和静态链接库方式),具体例子见 source/example/consoledemo/main.cpp

使用x3LoadLibrary和x3FreeLibrary函数来加载插件,而不是用LoadLibrary或LoadLibraryA,原因后者只能在Windows上才能使用。而使用x3LoadLibrary则同时适用于Windows/Linux/MacOSX等系统,对于Windows平台还对GCC编译方式进行了修正,这样确保能正常加载插件。

Clone this wiki locally