内置C++模块的注册

2020-03-27  本文已影响0人  orgcheng

node.cc类的InitializeNodeWithArgs方法中,调用了binding::RegisterBuiltinModules();方法,主要是用来注册内置的C++模块的。

// node_bindding.cc文件

// Call built-in modules' _register_<module name> function to
// do module registration explicitly.
void RegisterBuiltinModules() {
#define V(modname) _register_##modname();
  NODE_BUILTIN_MODULES(V)
#undef V
}
//通过使用宏定义,最终调用下面的方法
// _register_buffer();
// _register_config();
// _register_contextify();
// _register_domain();
// ...

#define NODE_BUILTIN_MODULES(V)                                                \
  NODE_BUILTIN_STANDARD_MODULES(V)                                             \
  NODE_BUILTIN_OPENSSL_MODULES(V)                                              \
  NODE_BUILTIN_ICU_MODULES(V)                                                  \
  NODE_BUILTIN_REPORT_MODULES(V)                                               \
  NODE_BUILTIN_PROFILER_MODULES(V)                                             \
  NODE_BUILTIN_DTRACE_MODULES(V)

#define NODE_BUILTIN_STANDARD_MODULES(V)                                       \
  V(buffer)                                                                    \
  V(config)                                                                    \
  V(contextify)                                                                \
  V(domain)                                                                    \
  V(fs)                                                                        \
  V(fs_dir)                                                                    \
  V(fs_event_wrap)                                                             \
  V(heap_utils)                                                                \
  V(js_stream)                                                                 \
  V(module_wrap)                                                               \
  V(native_module)                                                             \
  V(options)                                                                   \
  V(os)                                                                        \
  V(process_wrap)                                                              \
  V(process_methods)                                                           \
  V(symbols)                                                                   \
  V(timers)                                                                    \
  V(util)                                                                      \
  V(uv)                                                                        \
  V(v8)                                                                        \
  

#define NODE_BUILTIN_MODULES(V)                                                \
  NODE_BUILTIN_STANDARD_MODULES(V)                                             \
  NODE_BUILTIN_OPENSSL_MODULES(V)                                              \
  NODE_BUILTIN_ICU_MODULES(V)                                                  \
  NODE_BUILTIN_REPORT_MODULES(V)                                               \
  NODE_BUILTIN_PROFILER_MODULES(V)                                             \
  NODE_BUILTIN_DTRACE_MODULES(V)

// This is used to load built-in modules. Instead of using
// __attribute__((constructor)), we call the _register_<modname>
// function for each built-in modules explicitly in
// binding::RegisterBuiltinModules(). This is only forward declaration.
// The definitions are in each module's implementation when calling
// the NODE_MODULE_CONTEXT_AWARE_INTERNAL.
#define V(modname) void _register_##modname();
NODE_BUILTIN_MODULES(V)
#undef V
    
// 声明刚才调用的方法
// _register_buffer();
// _register_config();
// _register_contextify();
// _register_domain();
// ...    

上面的代码只是调用方法和声明方法,实际的方法在哪里实现的呢?

发现每个C++内置模块的代码中,最后一句都有下面类似的语句

NODE_MODULE_CONTEXT_AWARE_INTERNAL(buffer, node::Buffer::Initialize)

找到宏定义NODE_MODULE_CONTEXT_AWARE_INTERNAL

// node_binding.h

#define NODE_MODULE_CONTEXT_AWARE_INTERNAL(modname, regfunc)                   \
  NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_INTERNAL)

#define NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags)           \
  static node::node_module _module = {                                         \
      NODE_MODULE_VERSION,                                                     \
      flags,                                                                   \
      nullptr,                                                                 \
      __FILE__,                                                                \
      nullptr,                                                                 \
      (node::addon_context_register_func)(regfunc),                            \
      NODE_STRINGIFY(modname),                                                 \
      priv,                                                                    \
      nullptr};                                                                \
  void _register_##modname() { node_module_register(&_module); }

// 定义_module变量,然后创建_register_##modname相关的方法


// Globals per process
static node_module* modlist_internal;
static node_module* modlist_linked;
static thread_local node_module* thread_local_modpending;

// This is set by node::Init() which is used by embedders
bool node_is_initialized = false;

extern "C" void node_module_register(void* m) {
  struct node_module* mp = reinterpret_cast<struct node_module*>(m);

  if (mp->nm_flags & NM_F_INTERNAL) {
    mp->nm_link = modlist_internal;
    modlist_internal = mp;
  } else if (!node_is_initialized) {
    // "Linked" modules are included as part of the node project.
    // Like builtins they are registered *before* node::Init runs.
    mp->nm_flags = NM_F_LINKED;
    mp->nm_link = modlist_linked;
    modlist_linked = mp;
  } else {
    thread_local_modpending = mp;
  }
}
上一篇下一篇

猜你喜欢

热点阅读