`
yangzb
  • 浏览: 3521532 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

codeblocks中plugin的实现

    博客分类:
  • C++
阅读更多

快乐虾 http://blog.csdn.net/lights_joy/ lights@hb165.com

本文适用于

codeblocks-8.02

vs2005

 

 

 

1.1     Plugin 加载

Codeblocks plugin 放在可执行文件目录下的 share\CodeBlocks\plugins 子目录中,全部以 DLL 的形式存在。在 codeblock 启动时会调用如下函数:

int PluginManager::ScanForPlugins( const wxString& path)

{

………………………………… ..

    wxDir dir(path);

    wxString filename;

    wxString failed;

    bool ok = dir.GetFirst(&filename, PluginsMask, wxDIR_FILES);

    while (ok)

    {

…………………… .

        // load manifest

        m_pCurrentlyLoadingManifestDoc = 0;

        if (ReadManifestFile(filename))

        {

            if (LoadPlugin(path + _T( '/' ) + filename))

                ++count;

            else

                failed << _T( '\n' ) << filename;

        }

        delete m_pCurrentlyLoadingManifestDoc;

        m_pCurrentlyLoadingManifestDoc = 0;

        ok = dir.GetNext(&filename);

}

………………………………… ..

}

在上述代码中,将首先读取与 dll 同名的 manifest ,其实它就是一个放在 share/codeblocks 子目录下的同名 zip 文件,这个 zip 文件中两个文件: manifest.xml configuration.xrc ,其实这两个文件都是 XML 文档, manifest.xml 描述了这个插件的功能,作者等信息,而另一个文件则是一些配置信息。

在读取 manifest 成功后将调用 LoadPlugin 函数:

bool PluginManager::LoadPlugin( const wxString& pluginName)

{

    // clear registration temporary vector

    m_RegisteredPlugins.clear();

 

    // load library

    m_CurrentlyLoadingFilename = pluginName;

    m_pCurrentlyLoadingLib = LibLoader::LoadLibrary(pluginName);

    if (!m_pCurrentlyLoadingLib->IsLoaded())

    {

        Manager::Get()->GetLogManager()->LogError(F(_T( "%s: not loaded (missing symbols?)" ), pluginName.c_str()));

        LibLoader::RemoveLibrary(m_pCurrentlyLoadingLib);

        m_pCurrentlyLoadingLib = 0;

        m_CurrentlyLoadingFilename.Clear();

        return false ;

    }

 

    // by now, the library has loaded and its global variables are initialized.

    // this means it has already called RegisterPlugin()

    // now we can actually create the plugin(s) instance(s) :)

 

    // try to load the plugin(s)

    std::vector<PluginRegistration>::iterator it;

    for (it = m_RegisteredPlugins.begin(); it != m_RegisteredPlugins.end(); ++it)

    {

        PluginRegistration& pr = *it;

        cbPlugin* plug = 0L;

        try

        {

            plug = pr.createProc();

        }

        catch (cbException& exception)

        {

            exception.ShowErrorMessage( false );

             continue ;

        }

 

        // all done; add it to our list

        PluginElement* plugElem = new PluginElement;

        plugElem->fileName = m_CurrentlyLoadingFilename;

        plugElem->info = pr.info;

        plugElem->library = m_pCurrentlyLoadingLib;

        plugElem->freeProc = pr.freeProc;

        plugElem->plugin = plug;

        m_Plugins.Add(plugElem);

 

        SetupLocaleDomain(pr.name);

 

        Manager::Get()->GetLogManager()->DebugLog(F(_T( "%s: loaded" ), pr.name.c_str()));

    }

 

    if (m_RegisteredPlugins.empty())

    {

        // no plugins loaded from this library, but it's not an error

        LibLoader::RemoveLibrary(m_pCurrentlyLoadingLib);

    }

    m_pCurrentlyLoadingLib = 0;

    m_CurrentlyLoadingFilename.Clear();

    return true ;

}

这个函数首先调用 LibLoader::LoadLibrary 加载 DLL ,实际上它就是使用 LoadLibrary 这个 API 来加载 DLL

在加载完成后,按照注释的说明,这个 DLL 中应该调用 RegisterPlugin 函数进行自我注册,这其中当然包括创建实例这样回调函数,然后上述函数很自然地使用这样的回调函数创建 Plugin 的实例。然后用一个 PluginElement 来描述它,这个 plugElem 将用于主界面的菜单等位置。

从上述代码还可以看出,插件至少应该能创建一个 cbPlugin 的实例。

1.2     插件注册

从调用过程的注释可以知道,在加载 DLL 时,它应该能够调用 RegisterPlugin codeblock 进行注册,下面以 astyle 这个插件为例看看它的注册过程。

在这个插件中定义了一个全局变量:

namespace

{

    PluginRegistrant<AStylePlugin> reg(_T( "AStylePlugin" ));

}

除此之外没有其它东西可以在 DLL 加载时执行代码,看看 PluginRegistrant 这个类:

/** @brief Plugin registration object.

    *

  * Use this class to register your new plugin with Code::Blocks.

  * All you have to do is instantiate a PluginRegistrant object.

  * @par

  * Example code to use in one of your plugin's source files (supposedly called "MyPlugin"):

  * @code

  * namespace

  * {

  *     PluginRegistrant<MyPlugin> registration("MyPlugin");

  * }

  * @endcode

  */

template < class T> class PluginRegistrant

{

    public :

        /// @param name The plugin's name.

        PluginRegistrant( const wxString& name)

        {

             Manager::Get()->GetPluginManager()->RegisterPlugin(name, // plugin's name

                                                                &CreatePlugin, // creation

                                                                &FreePlugin, // destruction

                                                                &SDKVersion); // SDK version

        }

 

        static cbPlugin* CreatePlugin()

        {

            return new T;

        }

 

        static void FreePlugin(cbPlugin* plugin)

        {

            delete plugin;

        }

 

        static void SDKVersion( int * major, int * minor, int * release)

        {

            if (major) *major = PLUGIN_SDK_VERSION_MAJOR;

            if (minor) *minor = PLUGIN_SDK_VERSION_MINOR;

            if (release) *release = PLUGIN_SDK_VERSION_RELEASE;

        }

};

由此可见,在主程序加载 DLL 后还将调用 PluginRegistrant ::CreatePlugin 这个回调函数,而这个回调函数将创建一个 AStylePlugin 的实例。

1.3     Plugin 功能实现

仍以 astyle 为例进行分析。 Codeblocks plugin 分为几类:

cbCompilerPlugin

cbDebuggerPlugin

cbToolPlugin

cbMimePlugin

cbCodeCompletionPlugin

cbWizardPlugin

astyle 要完成代码格式化的功能,因而它选择了 cbToolPlugin 进行扩展:

class AStylePlugin : public cbToolPlugin

{

  public :

    AStylePlugin();

    ~AStylePlugin();

    int Configure();

    int GetConfigurationGroup() const { return cgEditor; }

    cbConfigurationPanel* GetConfigurationPanel(wxWindow* parent);

    int Execute();

    void OnAttach(); // fires when the plugin is attached to the application

    void OnRelease( bool appShutDown); // fires when the plugin is released from the application

};

呵呵,看着好像挺简单的。

 

 

分享到:
评论

相关推荐

    codeblocks

    Code::Blocks is a free C, C++ and Fortran IDE built to meet the most demanding needs of its users. It is designed to be very extensible and fully configurable. ...Built around a plugin frame

    CodeBlocks使用说明书

    - **定义**: 项目视图是CodeBlocks IDE中用于显示当前打开项目的界面部分。 - **功能**: 显示所有在特定时间内打开的项目。 - **特点**: 用户可以通过这个视图方便地管理和切换不同的项目。 **1.2 符号标签(Symbols...

    codeblocks10.05安装包

    Built around a plugin framework, Code::Blocks can be extended with plugins. Any kind of functionality can be added by installing/coding a plugin. For instance, compiling and debugging functionality is...

    codeBlocks 10.05教程.rar

    例如,在Ubuntu上可以使用`apt-get install codeblocks`命令进行安装。 2. **MacOS X下的安装**:在MacOS X系统上,可以从官方网站下载dmg安装包进行安装。 3. **搭配高版本gcc编译器**:如果需要使用更高版本的...

    CodeBlocks.zip

    Built around a plugin framework, Code::Blocks can be extended with plugins. Any kind of functionality can be added by installing/coding a plugin. For instance, compiling and debugging functionality is...

    vim之IDE进化实录 V0.2

    在软件开发过程中,随着项目的不断增大和复杂化,简单的文本编辑器已难以满足需求,集成开发环境(Integrated Development Environment,简称IDE)成为了开发者的首选工具。而在Linux平台下,如何将Vim配置成为一个...

    ubuntu 桌面速配

    以上配置可以帮助解决 CodeBlocks 中的乱码问题。 #### 五、总结 通过本文介绍的一系列软件和插件,可以显著提升 Ubuntu 11.10 的桌面使用体验。无论是多媒体播放、文档查看还是网络通信,都能够得到很好的支持。...

    tutorial:记录重要主题

    这些插件可能包括用于添加代码高亮的`gitbook-plugin-prismjs`,或者用于插入实时代码编辑器的`gitbook-plugin-codeblocks`。掌握如何选择和使用合适的插件,能极大提升你的Gitbook文档质量。 4. **学习项目** ...

    maya-math-nodes:Autodesk Maya的数学节点集合

    -G "CodeBlocks - Unix Makefiles"make该版本会在每个平台的默认安装目录中查找Maya,但是您始终可以为其提供自定义路径: -DMAYA_LOCATION=/apps/autodesk/同样,该构建默认为Maya版本2018,可以如下更改: -DMAYA...

Global site tag (gtag.js) - Google Analytics