0

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

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. UpdateStatus() 调用本机库,该库将状态返回给称为 SetStatus(NativeStatus) 的已知命名方法
  4. SetStatus() 创建一个 'JSStatus',从 nativeStatus 复制值
  5. SetStatus() 将“JSStatus”对象传递给称为 StatusUpdated(JSStatus) 的已知 JavaScript 函数

我被困在#5 上,因为似乎没有办法在 C++ 中“新建”一个 Nan::ObjectWrap,然后将该对象传递给 Javascript。

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

4

1 回答 1

2

似乎没有办法在 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);
}
于 2018-01-24T21:40:47.207 回答