节点解释器是否在节点二进制文件中寻找核心模块(比如说“ fs”)?如果是,这些模块是否打包为js文件。我们的代码中引用的核心模块是否先转换为c / c ++代码然后执行?例如,我在_tls_common.js(https://github.com/nodejs/node/blob/master/lib/_tls_common.js)文件中看到一个名为“ loadPKCS12”的方法,并且我看到该方法被引用/定义的唯一位置是在“ node_crypto.cc”文件中({{3 }})。那么,节点如何将javascript中的一种方法与c / c ++文件中定义的方法链接起来?
这是_tls_common.js文件的摘录,其中使用了“ loadPKCS12”方法:
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
}
}
} else {
const buf = toBuf(options.pfx);
const passphrase = options.passphrase;
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
答案 0 :(得分:1)
此处提出了两个不同(但看似相关)的问题。第一个是:“核心模块如何工作?”。第二个是“ NodeJS如何让c ++代码在JavaScript中被引用和执行?”。让我们一个一个地拿他们。
核心模块如何工作?
核心模块与NodeJS二进制文件一起打包。而且,尽管它们与二进制文件一起打包,但打包之前不会转换为c ++代码。在节点进程的引导过程中,内部模块为loaded into memory。程序执行时,假设require('fs')
,require函数只是从缓存中返回已经加载的模块。内部模块的实际加载显然发生在in c++ code。
NodeJS如何让c ++代码在JS中被引用?
此功能部分来自V8引擎,该引擎提供了在C ++中创建和管理JS构造的功能,另一部分来自NodeJS / LibUV,后者在V8之上创建了一个包装器以提供执行环境。有关此类节点模块的文档可以为accessed here。如文档所述,这些c ++模块可以像其他任何普通JS模块一样通过要求在JS文件中使用。
您的在JS(loadPKCS12
)中使用c ++函数的示例是NodeJS内部c ++功能的更特殊情况。从loadPKCS12
c ++模块导入的SecureContext
的对象上调用crypto
。如果您点击上面_tls_common.js
中SecureContext导入的链接,您将看到未使用require()
加载加密货币,而是使用一种特殊的(全局)方法internalBinding
获取引用。 。在node_crypto.cc
文件的last line中,注册了内部模块crypto
的初始化程序。按照初始化链,node::crypto::Initialize
调用node::crypto::SecureContext::Initialize
来创建函数模板,分配适当的原型方法并将其导出到target
上。最终,这些从C ++ world导出的功能通过internalBinding
导入并在JS-World中使用。