【问题标题】:Node-addon-api - construct ObjectWrap from C++Node-addon-api - 从 C++ 构造 ObjectWrap
【发布时间】:2022-10-21 21:50:56
【问题描述】:

我是 NAPI 新手,我正在尝试将旧 Nan 代码转换为 NAPI。

发生的事情是我有这样的结构:

class PointWrapper : public Napi::ObjectWrap<PointWrapper> {
public:
  static void init(Napi::Env env, Napi::Object exports);
  PointWrapper(const Napi::CallbackInfo& info);
private:
  Point point;
}

而且我以正确的方式包装了所有内容,因此如果我调用 JS new Pointer(1, 2),它将实例化 PointerWrapper 并将正确的字段设置为 Point。到目前为止,一切都很好。

现在,问题是稍后我有一个包含Range 的C++ 代码-Range 基本上是startend,每个都包含一个Point

我也有RangeWrapper,它与PointWrapper 做同样的事情,但对于范围。这个RangeWrapper 有一个getStart,基本上需要返回一个PointWrapper。

现在,我如何从RangeWrapper 实例化PointWrapper?基本上,我想要PointWrapper 上的构造函数,给出Point,我可以得到PointWrapper,所有这些都是在C++ 中而不是在JS 中。可能吗?我看到的每个代码都试图从里面PointWrapper,从不外部

【问题讨论】:

  • 任何人都找到了解决方案。

标签: c++ node.js constructor node-addon-api


【解决方案1】:

好的,所以我找到了一个解决方案 - 它很笨拙,但至少它有效。我要做的第一件事就是让“构造函数”成为其他地方可以使用的变量。所以我改变了我的班级有一个*constructor指针:

class PointWrapper : public Napi::ObjectWrap<PointWrapper> {
public:
  static void init(Napi::Env env, Napi::Object exports);
  PointWrapper(const Napi::CallbackInfo& info);
  static Napi::FunctionReference *constructor; // <-- Added this
private:
  Point point;
};

然后在我的init 实现(文件point-wrapper.cpp)上,我使用这个构造函数来“构造”Point

Napi::FunctionReference *PointWrapper::constructor; // <-- Added this
void PointWrapper::init(Napi::Env env, Napi::Object exports) {
  Napi::Function func = DefineClass(env, "Point", {
    // methods, etc...
  });

  constructor = new Napi::FunctionReference(); // <-- Used it here
  *constructor = Napi::Persistent(func); // <-- and here
  exports.Set("Point", func);
}

因此,要实例化PointWrapper,我需要调用构造函数,然后解包。现在,类本身只有一个可能的构造函数,它接收Napi::CallbackInfo&amp; info。为了用 C++ 方面的东西来实例化这个类,我们需要将一个 C++ 对象“包装”到Napi::External 中:

// Supposing you have a point already created:
auto wrapped = Napi::External<Point>::New(env, &Point);
Napi::Value pointWrapperAsVal = PointWrapper::constructor->New({ wrapped });

最后,让控制器明白可以使用Napi::External 对象调用它:

PointWrapper::PointWrapper(const Napi::CallbackInfo& info) 
                   : Napi::ObjectWrap<PointWrapper>(info) {
  if(info[0].IsExternal()) {
    auto point = info[0].As<Napi::External<Point>>();
    this->point = *point.Data();
  } else {
    // normal code
  }
}

请记住,pointWrapperAsValNapi::Value。如果您需要从 CPP 使用它,您可能需要转换为正确的“类型” - 例如,使用 PointWrapper::Unwrap(pointWrapperAsVal)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多