news 2026/1/20 8:42:07

Object Wrap

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Object Wrap

对象包装器(Object Wrap)

Napi::ObjectWrap<T>类继承自Napi::InstanceWrap<T>类。

Napi::ObjectWrap<T>类用于将 C++ 代码的生命周期绑定到 JavaScript 对象上。绑定完成后,每当创建一个 JavaScript 对象实例时,对应的 C++ 类实例也会被创建;当调用 JavaScript 对象上定义为InstanceMethod的方法时,被包装的 C++ 类中对应的 C++ 方法会被触发执行。

要实现包装器,必须继承Napi::ObjectWrap<T>类 —— 该类包含了将 JavaScript 代码与 C++ 对象连接起来的所有底层逻辑。继承Napi::ObjectWrap的类可在 JavaScript 中通过new运算符实例化,其方法也可直接从 JavaScript 中调用。「包装(wrap)」一词指的是将类的方法和状态整合在一起的方式,因为你需要编写自定义代码来桥接 C++ 类的每个方法。

⚠️ 注意:当 JavaScript 对象被垃圾回收时,C++ 析构函数的调用可能会延迟到后续某个时间点。在此期间,Value()方法会返回空值。

示例

#include <napi.h> class Example : public Napi::ObjectWrap<Example> { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); Example(const Napi::CallbackInfo& info); static Napi::Value CreateNewItem(const Napi::CallbackInfo& info); private: double _value; Napi::Value GetValue(const Napi::CallbackInfo& info); Napi::Value SetValue(const Napi::CallbackInfo& info); }; Napi::Object Example::Init(Napi::Env env, Napi::Object exports) { // 该方法用于关联访问器和方法的回调函数 Napi::Function func = DefineClass(env, "Example", { InstanceMethod<&Example::GetValue>("GetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), InstanceMethod<&Example::SetValue>("SetValue", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), StaticMethod<&Example::CreateNewItem>("CreateNewItem", static_cast<napi_property_attributes>(napi_writable | napi_configurable)), }); Napi::FunctionReference* constructor = new Napi::FunctionReference(); // 为类构造函数创建持久引用。这能区分 // 调用类原型上的函数和调用类实例上的函数这两种场景。 *constructor = Napi::Persistent(func); exports.Set("Example", func); // 将构造函数存储为插件实例数据。这能让该插件 // 支持在多个工作线程上运行多个实例,也支持在同一线程的不同上下文 // 中运行多个实例。 // // 默认情况下,此处设置在环境中的值会在插件卸载时通过 `delete` 运算符销毁, // 但也可以自定义销毁器(deleter)。 env.SetInstanceData<Napi::FunctionReference>(constructor); return exports; } Example::Example(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Example>(info) { Napi::Env env = info.Env(); // ... Napi::Number value = info[0].As<Napi::Number>(); this->_value = value.DoubleValue(); } Napi::Value Example::GetValue(const Napi::CallbackInfo& info){ Napi::Env env = info.Env(); return Napi::Number::New(env, this->_value); } Napi::Value Example::SetValue(const Napi::CallbackInfo& info){ Napi::Env env = info.Env(); // ... Napi::Number value = info[0].As<Napi::Number>(); this->_value = value.DoubleValue(); return this->GetValue(info); } // 初始化原生插件 Napi::Object Init (Napi::Env env, Napi::Object exports) { Example::Init(env, exports); return exports; } // 使用 Init 阶段存储的构造函数创建新实例 Napi::Value Example::CreateNewItem(const Napi::CallbackInfo& info) { // 获取在 `Init()` 阶段存储的实例数据。我们仅在其中存储了构造函数, // 因此此处取出它,用于创建该构造函数对应的 JS 类的新实例。 Napi::FunctionReference* constructor = info.Env().GetInstanceData<Napi::FunctionReference>(); return constructor->New({ Napi::Number::New(info.Env(), 42) }); } // 注册并初始化原生插件 NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

上述代码可在 JavaScript 中按如下方式使用:

'use strict' const { Example } = require('bindings')('addon') const example = new Example(11) console.log(example.GetValue()) // 输出 11 example.SetValue(19) console.log(example.GetValue()); // 输出 19

初始化阶段必须调用Napi::ObjectWrap::DefineClass()方法来关联访问器和方法的回调函数。该方法接收一组属性描述符,这些描述符可通过基类的各类静态方法构造。

当 JavaScript 代码调用构造函数时,构造函数回调会创建一个新的 C++ 实例,并将其「包装」到新创建的 JavaScript 对象中。

当 JavaScript 代码调用类上的方法或属性访问器时,对应的 C++ 回调函数会被执行。

对于包装对象,可能难以区分「调用类原型上的函数」和「调用类实例上的函数」这两种场景。因此,最佳实践是保存类构造函数的持久引用 —— 通过检查this对象与类构造函数的关系,可区分这两种场景。

方法

构造函数(Constructor)

创建一个包装了原生实例的 JavaScript 对象新实例。

Napi::ObjectWrap(const Napi::CallbackInfo& callbackInfo);
  • [in] callbackInfo:表示当前 JavaScript 请求各组成部分的对象。

Unwrap

提取被包装在 JavaScript 对象中的原生实例。

static T* Napi::ObjectWrap::Unwrap(Napi::Object wrapper);
  • [in] wrapper:包装了原生实例的 JavaScript 对象。

返回被包装在 JavaScript 对象中的原生实例。传入Napi::Object后,该方法能获取被包装的 C++ 对象指针,进而访问该类内的字段、调用方法等。多数场景下无需调用Unwrap—— 在继承ObjectWrap的类的方法中,可直接使用this指针访问包装对象。

DefineClass

定义一个包含构造函数、静态属性、实例属性、静态方法、实例方法的 JavaScript 类。

static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::initializer_list<PropertyDescriptor>& properties, void* data = nullptr);
  • [in] env:用于构造 JavaScript 类的运行环境。
  • [in] utf8name:以空字符结尾的字符串,表示 JavaScript 构造函数的名称。
  • [in] properties:用于描述类的静态 / 实例属性和方法的属性描述符初始化列表(详见:类属性与描述符)。
  • [in] data:用户提供的数据,会作为Napi::CallbackInfodata属性传入构造函数回调。

返回表示该类构造函数的Napi::Function对象。

DefineClass

定义一个包含构造函数、静态属性、实例属性、静态方法、实例方法的 JavaScript 类。

static Napi::Function Napi::ObjectWrap::DefineClass(Napi::Env env, const char* utf8name, const std::vector<PropertyDescriptor>& properties, void* data = nullptr);
  • [in] env:用于构造 JavaScript 类的运行环境。
  • [in] utf8name:以空字符结尾的字符串,表示 JavaScript 构造函数的名称。
  • [in] properties:用于描述类的静态 / 实例属性和方法的属性描述符向量(详见:类属性与描述符)。
  • [in] data:用户提供的数据,会作为Napi::CallbackInfodata属性传入构造函数回调。

返回表示该类构造函数的Napi::Function对象。

OnCalledAsFunction

自定义Napi::ObjectWrap<T>类在 JavaScript 中被当作函数调用(未使用new运算符)时的行为。

该场景下的默认行为是抛出一个Napi::TypeError,错误信息为「Class constructors cannot be invoked without 'new'(类构造函数必须使用 'new' 调用)」。在派生类中定义该公有方法可覆盖此默认行为。

例如,你可在内部通过new运算符重新调用 JavaScript 构造函数(通过Napi::Function::New(const std::vector<napi_value> &args))并返回结果对象;也可实现完全自定义的逻辑(如Date()作为函数调用时返回字符串)。

static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
  • [in] callbackInfo:表示当前 JavaScript 请求各组成部分的对象。

Finalize

提供执行仅依赖基础 Node API 的清理代码的时机(如有需要)。可重写该方法实现自定义逻辑(详见「终结化(Finalization)」)。

virtual void Finalize(Napi::BasicEnv env);
  • [in] envNapi::Env运行环境。

Finalize

提供执行依赖非基础 Node API 的清理代码的时机。可重写该方法实现自定义逻辑。

⚠️ 注意:定义该方法会导致底层T*数据的销毁操作推迟到垃圾回收周期结束后。由于Napi::Env可访问非基础 Node API,其逻辑无法与垃圾回收器在同一个事件循环周期(tick)中执行。

virtual void Finalize(Napi::Env env);
  • [in] envNapi::Env运行环境。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, StaticVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, StaticMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, StaticVoidMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, StaticMethodCallback method, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticVoidMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数(无返回值)。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态方法名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticVoidMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticMethod

创建表示 JavaScript 类静态方法的属性描述符。

template <StaticMethodCallback method> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticMethod(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] method:表示 JavaScript 类静态方法的原生函数。
  • [in] name:表示类静态方法名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用该方法时传入的用户自定义数据。

返回表示 JavaScript 类静态方法的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor( const char* utf8name, StaticGetterCallback getter, StaticSetterCallback setter, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] utf8name:以空字符结尾的字符串,表示类的静态访问器属性名称。
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name, StaticGetterCallback getter, StaticSetterCallback setter, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] name:表示静态访问器名称的Napi::Symbol对象。
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor( const char* utf8name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数(默认值为nullptr)。
  • [in] utf8name:以空字符结尾的字符串,表示类的静态访问器属性名称。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticAccessor

创建表示 JavaScript 类静态访问器属性的属性描述符。

template <StaticGetterCallback getter, StaticSetterCallback setter=nullptr> static Napi::PropertyDescriptor Napi::ObjectWrap::StaticAccessor(Symbol name, napi_property_attributes attributes = napi_default, void* data = nullptr);
  • [in] getter:对 JavaScript 类的该属性执行读取(get)操作时调用的原生函数。
  • [in] setter:对 JavaScript 类的该属性执行写入(set)操作时调用的原生函数(默认值为nullptr)。
  • [in] name:表示静态访问器名称的Napi::Symbol对象。
  • [in] attributes:与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。
  • [in] data:调用获取器(getter)或设置器(setter)时传入的用户自定义数据。

返回表示 JavaScript 类静态访问器属性的Napi::PropertyDescriptor对象。

StaticValue

创建表示 JavaScript 类静态值属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue( const char* utf8name, Napi::Value value, napi_property_attributes attributes = napi_default);
  • [in] utf8name:以空字符结尾的字符串,表示静态属性的名称。
  • [in] value:读取(get)该属性时返回的值。
  • [in] attributes:除napi_static外,与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。

返回表示 JavaScript 类静态值属性的Napi::PropertyDescriptor对象。

StaticValue

创建表示 JavaScript 类静态值属性的属性描述符。

static Napi::PropertyDescriptor Napi::ObjectWrap::StaticValue(Symbol name, Napi::Value value, napi_property_attributes attributes = napi_default);
  • [in] nameNapi::Symbol对象,其值用于标识静态属性的名称。
  • [in] value:读取(get)该属性时返回的值。
  • [in] attributes:除napi_static外,与该属性关联的特性,可为一个或多个napi_property_attributes枚举值。

返回表示 JavaScript 类静态值属性的Napi::PropertyDescriptor对象。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/4 6:53:36

MediaPipe Samples完整指南:如何快速构建高性能机器学习应用

MediaPipe Samples完整指南&#xff1a;如何快速构建高性能机器学习应用 【免费下载链接】mediapipe-samples 项目地址: https://gitcode.com/GitHub_Trending/me/mediapipe-samples MediaPipe Samples是Google官方提供的机器学习示例项目集合&#xff0c;为开发者提供…

作者头像 李华
网站建设 2025/12/28 9:10:19

在STM32上实现LCD中文显示完整示例

在STM32上实现LCD中文显示&#xff1a;从字库生成到屏幕输出的完整实战指南你有没有遇到过这样的场景&#xff1f;项目需要一个带界面的设备&#xff0c;客户明确要求&#xff1a;“必须支持中文菜单。”而你手里的开发板只是一块普通的STM32最小系统 一块TFT彩屏。没有操作系…

作者头像 李华
网站建设 2026/1/20 4:17:42

Kavita跨平台阅读服务器部署与优化完全指南

Kavita跨平台阅读服务器部署与优化完全指南 【免费下载链接】Kavita Kavita is a fast, feature rich, cross platform reading server. Built with a focus for manga and the goal of being a full solution for all your reading needs. Setup your own server and share yo…

作者头像 李华
网站建设 2025/12/30 8:35:23

YOLO模型训练周期预测:根据GPU算力估算完成时间

YOLO模型训练周期预测&#xff1a;根据GPU算力估算完成时间 在智能制造工厂的视觉质检线上&#xff0c;一个新缺陷检测任务刚刚立项——团队需要基于百万级图像数据训练一个高精度YOLOv8模型。项目经理问出那个经典问题&#xff1a;“这活儿多久能干完&#xff1f;” 没人敢轻…

作者头像 李华
网站建设 2026/1/19 8:19:03

2025最新!8个AI论文工具测评:本科生写毕业论文必备清单

2025最新&#xff01;8个AI论文工具测评&#xff1a;本科生写毕业论文必备清单 2025年AI论文工具测评&#xff1a;为本科生量身打造的写作助手 随着人工智能技术的不断进步&#xff0c;越来越多的学术写作工具开始进入高校师生的视野。对于本科生而言&#xff0c;撰写毕业论文不…

作者头像 李华
网站建设 2025/12/28 9:07:51

YOLO训练数据格式转换:YOLO格式标注与GPU预处理

YOLO训练数据格式转换与GPU预处理&#xff1a;构建高效工业级目标检测流水线 在智能制造工厂的质检线上&#xff0c;一台高速摄像头每秒拍摄数十帧PCB板图像&#xff0c;系统必须在毫秒级内完成缺陷识别。然而工程师却发现&#xff0c;即便使用了A100显卡&#xff0c;模型训练…

作者头像 李华