快乐虾

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中plugin的实现相关推荐

  1. CRM中Plugin开发如何将功能放入多个模块

    近期做CRM的Plugin开发,发现Plugin中的功能必须全部放在一个DLL里,感觉不爽,如果我要用的功能在别人提供的DLL里,或有些功能需要在多个地方使用岂不是很难过? 用了VS2012的Dyna ...

  2. 在codeblocks中使用C++11标准,安装及配置方法

    原文:http://www.lai18.com/content/624976.html 用过的codeblocks的人都知道,这款软件是相当的棒.同时在2011年推出的C++11新标准也是非常的强大, ...

  3. 在CodeBlocks中完美使用WTL进行开发

    WTL 是 Windows Template Library 的缩写,WTL 功能不如MFC完善,但是比 MFC 更小巧,不依赖 MFC 的DLL.就是因为WTL可以编写出小巧的,不需要额外的DLL支 ...

  4. codeblocks中的输出double数据乱码问题

    出现的问题 看下面的一小段代码: #include<bits/stdc++.h> using namespace std; int main() {double x=-1.0;printf ...

  5. EOS中plugin之net_plugin

    EOS中plugin之net_plugin 这部分重点介绍EOS中的服务器端部分nodeos启动之后开启的另外一个重要的插件--net_plugin,这个插件主要负责服务器在网络中的接入.同步区块信息 ...

  6. AS 中 Plugin for Gradle 和 Gradle 之间的版本对应关系

    Plugin for Gradle 和 Gradle 之间的版本对应关系  来源:https://developer.android.com/studio/releases/gradle-plugin ...

  7. codeblocks调用matlab,matlab engine: 在Codeblocks中使用C++调用matlab | 学步园

    平台:XP,Code::Blocks 10.05(包含gcc 4.4.1),matlab 2010b 方式:C++调用matlab引擎 设置步骤: (一)系统变量:path中添加MinGW\bin; ...

  8. 在windows下codeblocks中配置pthread库

    转自:http://blog.csdn.net/u013172314/article/details/50846198 如果添加方法不正确,可能会出现pthread_create'未定义的引用,所以下 ...

  9. Qt文档阅读笔记-Qt4 Lower-Level API扩展Qt Applications(Qt4中Plugin的使用)解析与实例

    目录 官方解析 博主栗子 官方解析 Qt应用程序可以对插件进行扩展,要使用QPluginLoader这个类进行加载.插件可以提供任意的功能,而且不限制数据库驱动,图像格式,以及其他的Qt功能插件. 当 ...

最新文章

  1. 天猫国际618一骑绝尘,占中国跨境进口电商总订单超七成
  2. SNMPM 配置 [linux windows solaris]
  3. Node入门--6--文件系统-创建删除
  4. sql和python还有c语言_Python语言之原生sql整理
  5. python爬取岗位数据并分析_区块链岗位薪资高,Python爬取300个区块链岗位分析,龙虎榜出炉...
  6. Linux C: 内嵌汇编语法
  7. 测试计算机操作基础知识,计算机病毒基础知识测试
  8. Silverlight学习日记(三)
  9. Go语言通过odbc驱动连接华为高斯数据库
  10. Linux基础命令---ab测试apache性能
  11. Python自动绘制UML类图、函数调用图(Call Graph)
  12. ES2020 中 Javascript 10 个你应该知道的新功能
  13. APP UI自动化测试:框架选择、环境搭建、脚本编写……全总结
  14. Javashop-B2B2C多店铺系统,Javashop B2C开源电商系统下载
  15. 学生HTML个人网页作业作品——湘菜美食网页设计作品(12页) 美食网站设计与实现
  16. 概率论与数理统计--大数定律与中心极限定理
  17. SX1278、SX1276、SX1262的简单详解
  18. 知识产权侵权警告通知函范本要如何写
  19. 智能窗帘定时程序c语言,基于单片机智能窗帘控制系统设计
  20. 微信小程序——音乐播放器

热门文章

  1. 千手观音王牌对王牌_王牌技术面试的7个技巧
  2. Map集合的遍历(方式2)
  3. html选择框 树结构,带复选框tree树结构插件MultipleTreeSelect.js
  4. Linux磁盘分区格式化
  5. 大叔路遇女子被撞倒地 先拍照取证再扶人
  6. spring security 之 sec:authorize 失效
  7. mysql未定义_以mysql_开始的未定义引用错误
  8. 微信分享相关:报错“微信:包名不对,请检查包名是否与开放平台填写一致”
  9. Greenplum命令整理(二)数据库操作
  10. 【http post】post传输数据大小