美文网首页
内置C++模块的注册

内置C++模块的注册

作者: orgcheng | 来源:发表于2020-03-27 15:30 被阅读0次

    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;
      }
    }
    

    相关文章

      网友评论

          本文标题:内置C++模块的注册

          本文链接:https://www.haomeiwen.com/subject/wpiluhtx.html