从零开始创建一个插件
下面简单介绍在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。