我们在js中写代码:
const os = require('os')
os.networkInterfaces()
首先,require中的‘os’模块可以找到,因为有lib/os.js。 在os.js中,找到函数"networkInterfaces":
此函数的导出: 在os.js中可以看到此函数的导出:
module.exports = {
....
networkInterfaces,
....
};
此函数的定义:
function networkInterfaces() {
const data = getInterfaceAddresses();
const result = {};
if (data === undefined)
return result;
for (var i = 0; i < data.length; i += 7) {
const name = data[i];
const entry = {
address: data[i + 1],
netmask: data[i + 2],
family: data[i + 3],
mac: data[i + 4],
internal: data[i + 5],
cidr: getCIDR(data[i + 1], data[i + 2], data[i + 3])
};
const scopeid = data[i + 6];
if (scopeid !== -1)
entry.scopeid = scopeid;
const existing = result[name];
if (existing !== undefined)
existing.push(entry);
else
result[name] = [entry];
}
return result;
}
在定义中我们看到函数"getInterfaceAddresses",这个是通过V8导出的C++接口,在node_os.cc中看到:
void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
...
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
...
}
此文件最后:
NODE_MODULE_CONTEXT_AWARE_INTERNAL(os, node::os::Initialize)
宏定义在src\node_binding.h中,如下:
#define NODE_MODULE_CONTEXT_AWARE_INTERNAL(modname, regfunc) \
NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_INTERNAL)
NODE_MODULE_CONTEXT_AWARE_CPP宏定义在src\node_binding.h中,如下
#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); }
最后一行是对模块的注册:
void _register_##modname() { node_module_register(&_module);
那么在哪里调用的呢??
在node_binding.cc中看到宏定义:
#define V(modname) void _register_##modname();
所有注册os模块,应该是执行:V(os),那么搜一把:
// A list of built-in modules. In order to do module registration
// in node::Init(), need to add built-in modules in the following list.
// Then in binding::RegisterBuiltinModules(), it calls modules' registration
// function. This helps the built-in modules are loaded properly when
// node is built as static library. No need to depend on the
// __attribute__((constructor)) like mechanism in GCC.
#define NODE_BUILTIN_STANDARD_MODULES(V) \
...
V(fs) \
V(os) \
V(pipe_wrap)
...
在看这个宏定义 NODE_BUILTIN_STANDARD_MODULES 调用的地方:
#define NODE_BUILTIN_MODULES(V) \
NODE_BUILTIN_STANDARD_MODULES(V) \
NODE_BUILTIN_OPENSSL_MODULES(V) \
NODE_BUILTIN_ICU_MODULES(V) \
NODE_BUILTIN_PROFILER_MODULES(V) \
NODE_BUILTIN_DTRACE_MODULES(V)
这个宏定义 NODE_BUILTIN_MODULES 调用,在node_binding.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
}
函数 RegisterBuiltinModules 调用,在node.cc:
int InitializeNodeWithArgs(std::vector<std::string>* argv,
std::vector<std::string>* exec_argv,
std::vector<std::string>* errors) {
// Make sure InitializeNodeWithArgs() is called only once.
CHECK(!init_called.exchange(true));
...
// Register built-in modules
binding::RegisterBuiltinModules();
...
}
接下来上层调用依次是: node::InitializeOncePerProcess -> node::Start -> wmain/ main。
而入口函数是在node_main.cc中,根据不同环境,进入不同入口: wmain/ main。