从零开始创建一个插件

下面简单介绍在VC++中如何从零开始编写一个插件。

步骤1:利用VC++向导创建一个工程。

MFC、Win32、COM、ActiveX、EXE工程都可以。

步骤2:设置工程的包含路径,指定X3C的接口头文件路径。

例如添加一个包含路径“..\..\include\x3c”。

我是把x3c的 code\pkg_Core\Interface\ 下的所有文件复制到一个产品软件的 include\x3c\ 目录下的,所以填写了“..\..\include\x3c”,读者需要自己根据实际目录情况而定。

步骤3:在Stdafx.h中包含PluginInc.h,例如:

#include <UtilFunc/PluginInc.h>

步骤4:在工程中的任意一个CPP文件中包含 XModuleMacro.h 和 XModuleImpl.h 。

我一般是在单独新建的 Module.cpp 中包含这两个文件及下面要介绍的 XBEGIN_DEFINE_MODULE 组的。

#include <Module/XModuleMacro.h>
#include <Module/XModuleImpl.h>

步骤5:在这个CPP文件中添加类登记表:

XBEGIN_DEFINE_MODULE()
    //XDEFINE_CLASSMAP_ENTRY(CLSID_Example, Cx_Example)
XEND_DEFINE_MODULE()

步骤8中会介绍如何登记实现类。

这里面有个细节,此次用的是 XEND_DEFINE_MODULE() 而不是 XEND_DEFINE_MODULE_DLL() 或 XEND_DEFINE_MODULE_MFCEXTDLL(),其原因是VC++向导已经帮我们把DLL入口函数或者CWinApp派生类实现了,所以就使用最简单的宏 XEND_DEFINE_MODULE() 。如果你不想要向导帮你创建的代码,就可以使用 XEND_DEFINE_MODULE_DLL() 或 XEND_DEFINE_MODULE_MFCEXTDLL()。

现在编译工程,应该可以编译通过了,这样我们就得到了一个没有实现任何新接口的插件,此时其他工程是无法使用此插件的接口的。

但此时该插件内是可以调用别的插件接口的,例如在某个函数内添加下面的代码应该就能编译通过的:

    Cx_Interface<Ix_LogManager> pIFManager(x3::CLSID_LogManager);
    if (pIFManager)
    {
        pIFManager->PopGroup();
    }

步骤6:添加一个接口。

在工程中新建一个H文件,添加一个派生于 Ix_Object 的类或结构体,使用 X3DEFINE_IID 指定接口ID,然后添加自己的接口函数(纯虚函数),例如:

class ITest : public Ix_Object
{
public:
    X3DEFINE_IID(ITest);
    virtual void foo() = 0;
};

步骤7:实现此接口。

在工程中新建一个类,包含并继承刚才的接口,使用 X3BEGIN_CLASS_DECLARE 指定该类所支持的接口,例如:

#pragma once

#include "ITest.h"

class CTest : public ITest
{
    X3BEGIN_CLASS_DECLARE(CTest)
        X3DEFINE_INTERFACE_ENTRY(ITest)
    X3END_CLASS_DECLARE()
protected:
    CTest();
    virtual ~CTest();

private:
    virtual void foo();
};

在这个例子中有几处需要说明:

1、X3BEGIN_CLASS_DECLARE的参数为此类的类名;

2、使用X3DEFINE_INTERFACE_ENTRY指定此类要实现的各个接口,每继承实现一个接口就加一行;

3、如果此类还继承了其他接口实现类,则使用 X3USE_INTERFACE_ENTRY(基类) 加一行;

4、构造函数和析构函数设置为protected是为了不允许直接实例化;

5、接口函数设置为private是为了不允许直接调用实现类的函数,当然也可以改为protected或public的。

步骤8:将实现类登记到插件的类工厂表中,即加到 XBEGIN_DEFINE_MODULE 组中

#include "Test.h"

XBEGIN_DEFINE_MODULE()
    XDEFINE_CLASSMAP_ENTRY(CLSID_Test, CTest)
XEND_DEFINE_MODULE()

这里需要一个类ID常量,例如CLSID_Test,可以添加到接口头文件中,或者加到单独的头文件中,例如:

const X3CLSID CLSID_Test("499503c2-7b17-4607-9755-81bce77fe95c");

建议使用工具自动生成的UUID串。

还有一种较好的办法是基于X3C的模板工程Win32DllTempl或MFCExtTempl来创建插件工程。以Win32DllTempl为例,假如要创建MyTest插件:复制Win32DllTempl目录到新的目录,修改目录名和文件名为MyTest,将其中所有文件中的Win32DllTempl文字替换为MyTest。

原文地址:https://www.cnblogs.com/rhcad/p/2094950.html