如何将新的 Nan::ObjectWrap 从 C++ 传递给 Javascript?

How to pass a NEW Nan::ObjectWrap from C++ to Javascript?

我在我的 C++ 节点扩展中定义了以下包装 class。

class JSStatus : public Nan::ObjectWrap {
public:
    long statusCode;
    std::string statusMessage;
    std::string statusDetails;

    static NAN_MODULE_INIT(Init);
    static NAN_METHOD(New);
    static NAN_GETTER(HandleGetters);
    static NAN_SETTER(HandleSetters);
    static Nan::Persistent<v8::FunctionTemplate> constructor;
};

正常的调用顺序是这样的(全部在 Javascript 线程上):

  1. Javascript 调用 MyExtension::UpdateStatus(callbackFunction)
  2. UpdateStatus() 保存 'callbackFunction' 供 SetStatus()
  3. 稍后使用
  4. UpdateStatus() 调用本机库,该库 returns 状态为已知的命名方法,称为 SetStatus(NativeStatus)
  5. SetStatus() 创建一个 'JSStatus',从 nativeStatus
  6. 复制值
  7. SetStatus() 将 'JSStatus' 对象传递给已知的 javascript 函数 StatusUpdated(JSStatus)

我坚持#5,因为似乎没有办法在 C++ 中 "new" a Nan::ObjectWrap,然后将该对象传递给 Javascript。

这似乎很常见,足以被 NAN 涵盖,但我一直无法确定如何去做。有什么想法吗?

似乎无法 "new" C++ 中的对象并将其传递给 Javascript。我的解决方法是创建一个通用 JS 对象并一次向其添加一个字段。笨拙,但使用 NAN 并不难。

// Send status to Javascript
void sendStatus(JSStatus* status) {
    // Create callback parameters
    const int argc = 1;
    v8::Local<v8::Value> args[argc];

    // Create generic JS object for status
    v8::Local<v8::Object> jsObject = Nan::New<v8::Object>();

    // Create property names & values for each field
    v8::Local<v8::String> propName = Nan::New("statusCode").ToLocalChecked();
    v8::Local<v8::Value> propValue = Nan::New(status->statusCode);

    // Add field to JS object
    Nan::Set(jsObject, propName, propValue);

    // And again...
    propName = Nan::New("statusMessage").ToLocalChecked();
    propValue = Nan::New(status->statusMessage).ToLocalChecked();
    Nan::Set(jsObject, propName, propValue);

    // .... Etc., etc. for all the other fields ....

    // Set parameter to JS object
    args[0] = jsObject;

    // Pass status to Javascript
    v8::Local<v8::Value> jsReturnValue = jsStatusDelegate.Call(argc, args);
}