1

I am trying to write a native C++ module to include in a Node.js project -- I followed the guide here and have things setup pretty well.

The general idea is that I want to pass an array of integers to my C++ module to be sorted; the module then returns the sorted array.

However, I cannot compile using node-gyp build because I hit the following error:

error: no viable conversion from 'Local' to 'int *'

It is complaining about this code in my C++:

void Method(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();

    int* inputArray = args[0]; // <-- ERROR!

    sort(inputArray, 0, sizeof(inputArray) - 1);

    args.GetReturnValue().Set(inputArray);
}

This all makes conceptual sense to me -- the compiler can't magically cast arg[0] (presumably of type v8::Local) to an int*. Having said that, I cannot seem to find any way to get my argument successfully cast into a C++ integer array.

It should be known that my C++ is rather rusty, and I know next-to-nothing about V8. Can anyone point me in the right direction?

4

1 回答 1

2

这不是微不足道的:您首先需要将 JS 数组(内部表示为 a v8::Array)解包为可排序的东西(如 a std::vector),对其进行排序,然后将其转换回 JS 数组。

这是一个例子:

void Method(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();

    // Make sure there is an argument.
    if (args.Length() != 1) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "Need an argument")));
        return;
    }

    // Make sure it's an array.
    if (! args[0]->IsArray()) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "First argument needs to be an array")));
        return;
    }

    // Unpack JS array into a std::vector
    std::vector<int> values;
    Local<Array> input = Local<Array>::Cast(args[0]);
    unsigned int numValues = input->Length();
    for (unsigned int i = 0; i < numValues; i++) {
        values.push_back(input->Get(i)->NumberValue());
    }

    // Sort the vector.
    std::sort(values.begin(), values.end());

    // Create a new JS array from the vector.
    Local<Array> result = Array::New(isolate);
    for (unsigned int i = 0; i < numValues; i++ ) {
        result->Set(i, Number::New(isolate, values[i]));
    }

    // Return it.
    args.GetReturnValue().Set(result);
}

免责声明:我不是 v8 向导,也不是 C++ 向导,因此可能有更好的方法来做到这一点。

于 2015-11-13T21:16:36.177 回答