Node.js v14.20.0 文档


目录

C++ 插件#

中英对照

插件是用 C++ 编写的动态链接共享对象。 require() 函数可以将插件加载为普通的 Node.js 模块。 插件提供了 JavaScript 和 C/C++ 库之间的接口。

    你好世界#

    中英对照

    这个 "Hello world" 示例是一个简单的插件,用 C++ 编写,相当于以下 JavaScript 代码:

    
    

    
    

    
    

    上下文感知的插件#

    中英对照

    在某些环境中,可能需要在多个上下文中多次加载 Node.js 插件。 例如,Electron 运行时在单个进程中运行多个 Node.js 实例。 每个实例都有自己的 require() 缓存,因此当通过 require() 加载时,每个实例都需要原生插件才能正确运行。 这意味着插件必须支持多个初始化。

    
    

        
        
        工作线程的支持#

        中英对照

        为了从多个 Node.js 环境(例如主线程和工作线程)加载,插件需要:

          
          

          
          

          
          

          构建#

          中英对照

          编写源代码后,必须将其编译为二进制 addon.node 文件。 为此,请在项目的顶层创建名为 binding.gyp 的文件,使用类似 JSON 的格式描述模块的构建配置。 该文件由 node-gyp 使用,这是一个专门为编译 Node.js 插件而编写的工具。

          
          

          
          

          
          

          链接到 Node.js 自带的库#

          中英对照

          Node.js 使用静态链接库,例如 V8、libuv 和 OpenSSL。 所有插件都需要链接到 V8,也可以链接到任何其他依赖项。 通常,这就像包含适当的 #include <...> 语句(例如 #include <v8.h>)一样简单,node-gyp 将自动定位适当的头文件。 但是,有一些注意事项需要注意:

            使用 require() 加载插件#

            中英对照

            已编译的插件二进制文件的文件扩展名是 .node(与 .dll.so 相反)。 require() 函数用于查找具有 .node 文件扩展名的文件并将它们初始化为动态链接库。

            Node.js 的原生抽象#

            中英对照

            本文档中说明的每个示例都直接使用 Node.js 和 V8 API 来实现插件。 从一个 V8 版本到下一个版本(以及一个主要的 Node.js 版本到下一个版本),V8 API 可能并且已经发生了巨大的变化。 每次更改时,插件可能需要更新和重新编译才能继续运行。 Node.js 发布计划旨在最小化此类更改的频率和影响,但 Node.js 几乎无法确保 V8 API 的稳定性。

            Node-API#

            中英对照

            Node-API 是用于构建原生插件的 API。 它独立于底层 JavaScript 运行时(例如 V8),并作为 Node.js 自身的一部分进行维护。 此 API 将在 Node.js 的各个版本中保持稳定的应用程序二进制接口 (ABI)。 它旨在将插件与底层 JavaScript 引擎中的更改隔离开来,并允许为一个版本编译的模块无需重新编译即可在更高版本的 Node.js 上运行。 插件是使用本文档中概述的相同方法/工具(node-gyp 等)构建/打包的。唯一的区别是原生代码使用的 API 集。 使用 Node-API 中可用的函数,而不是使用 V8 或 Node.js 原生抽象的 API。

            
            

            插件示例#

            中英对照

            以下是一些旨在帮助开发人员入门的示例插件。 这些示例使用 V8 API。 请参阅在线 V8 手册以获取有关各种 V8 调用的帮助,以及 V8 的嵌入器指南以获取对所使用的几个概念(例如句柄、作用域、函数模板等)的解释。

            
            

            
            

            
            

            函数的参数#

            中英对照

            插件通常会暴露可以从 Node.js 中运行的 JavaScript 访问的对象和函数。 当从 JavaScript 调用函数时,输入参数和返回值必须映射到 C/C++ 代码和从 C/C++ 代码映射。

            
            

            
            

            回调#

            中英对照

            插件中的常见做法是将 JavaScript 函数传给 C++ 函数并从那里执行它们。 以下示例说明了如何调用此类回调:

            
            

            
            

            对象工厂#

            中英对照

            插件可以从 C++ 函数中创建和返回新对象,如下例所示。 创建并返回带有属性 msg 的对象,该属性与传给 createObject() 的字符串相呼应:

            
            

            
            

            函数工厂#

            中英对照

            另一个常见的场景是创建封装 C++ 函数并将它们返回给 JavaScript 的 JavaScript 函数:

            
            

            
            

            封装 C++ 对象#

            中英对照

            还可以以允许使用 JavaScript new 运算符创建新实例的方式封装 C++ 对象/类:

            
            

            
            

            
            

            
            

            
            

            封装对象的工厂#

            中英对照

            另外,可以使用工厂模式来避免使用 JavaScript new 运算符显式创建对象实例:

            
            

            
            

            
            

            
            

            
            

            
            

            传递封装的对象#

            中英对照

            除了封装和返回 C++ 对象之外,还可以通过使用 Node.js 辅助函数 node::ObjectWrap::Unwrap 将它们解包来传递被包装的对象。 以下示例显示了函数 add(),它可以将两个 MyObject 对象作为输入参数:

            
            

            
            

            
            

            返回顶部