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

时间:2018-01-18 22:40:06

标签: javascript node.js v8 node.js-addon node.js-nan

我在C ++ Node扩展中定义了以下包装类。

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()保存&#39; callbackFunction&#39;供SetStatus()
  3. 以后使用
  4. UpdateStatus()调用一个本机库,该库将状态返回给名为SetStatus(NativeStatus)的已知命名方法
  5. SetStatus()创建一个&#39; JSStatus&#39;,从nativeStatus复制值
  6. SetStatus()传递&#39; JSStatus&#39;对象称为StatusUpdated(JSStatus)
  7. 的已知javascript函数

    我坚持#5,因为似乎没有一种方式可以使用#&#34; new&#34;在C ++中使用Nan :: ObjectWrap,然后将该对象传递给Javascript。

    这似乎是一个足以让NAN覆盖的东西,但我一直无法确定如何做到这一点。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

似乎没有办法#34; new&#34; C ++中的一个对象并将其传递给Javascript。我的解决方法是创建一个通用的JS对象,并一次添加一个字段。 Klunky,但对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);
}