源代码解读 [EOS 源码分析] 03 - nodeos 插件是如何注册的?

Admin · 2019年12月21日 · 27 次阅读
本帖已被设为精华帖!

EOS 源码分析系列文章,由技术作者松果撰写。为帮助更多开发者了解,特获授权转载至此。感谢松果兄支持。

上一篇文章分析了nodeos如何读取config.ini和命令行参数中的配置项,main函数的参数被传递到application::initialize函数,内部对注册到application的插件进行了初始化,这篇文章来研究一下nodeos插件的注册流程。

nodeos插件的注册流程

1、插件加载的顺序

eos/programs/nodeos/CMakeLists.txt中,可以查找到nodeos插件加载的顺序:

img

target_link_libraries指令的作用是将目标文件与库文件进行链接,可以看到,第一个加载的插件是login_plugin,它的代码位于eos/plugins/login_plugin目录下。

2、注册插件

application.hpp中定义了注册插件的函数register_plugin

img

插件的注册是动态进行的,nodeos开始运行时会在程序加载阶段进行插件的注册。

login_plugin为例,eos/plugins/login_plugin目录下的login_plugin.cpp代码中,在eosio命名空间下有一句static语句:

static appbase::abstract_plugin& _login_plugin = app().register_plugin<login_plugin>();

这句代码在nodeos程序加载阶段会被执行,login_plugin把自己注册到application中。

application维护了几个保存插件相关的私有成员变量:

img

plugins是一个映射集合,用来保存已注册的插件;

initialized_plugins是一个动态数组,用来保存已初始化的插件;

running_plugins也是一个动态数组,用来保存运行中的插件。

调用register_plugin函数注册插件时,application会先调用find_plugin函数到plugins中查找该插件是否已被注册,如果是,直接返回该插件;否则创建一个新的插件实例,并添加到plugins中。

3、注册插件的依赖插件

注意register_plugin函数中有一句代码:

plug->register_dependencies();

nodeos的插件之间存在依赖关系,plugin的register_dependencies函数定义如下:

virtual void register_dependencies() {
  static_cast<Impl*>(this)->plugin_requires([&](auto& plug){});
}

它是一个虚函数,内部调用了plugin_requires函数,定义在eos/libraries/appbase/include/appbase/plugin.hpp中,被封装成了一个宏:

img

宏内部也调用了register_plugin

appbase::app().register_plugin<elem>()

即注册每个具体的插件后,会通过调用APPBASE_PLUGIN_REQUIRES宏来注册它依赖的其他插件。

还是以login_plugin为例,login_plugin.hpp中的代码如下:

img

APPBASE_PLUGIN_REQUIRES((chain_plugin)(http_plugin))

通过上面这句代码得知,login_plugin依赖于chain_pluginhttp_plugin,注册login_plugin插件后,会依次注册chain_plugin、http_plugin两个插件,以保证login_plugin可以正常运行。

下一篇文章来梳理nodeos各插件之间的依赖关系。

更多内容

币圈信息站开发目录

EOS开发系列目录

共收到 0 条回复
Admin 将本帖设为了精华贴 12月21日 12:04
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册