javascriptc++jsonnode.jsnode.js-nan

Pass arbitrary Javascript data object to Node.js C++ addon


I have a Node.js addon written in C++ using Nan. Works fantastically. However, I've not been able to figure out how to have my Node Javascript code pass an arbitrary data object (ex. {attr1:42, attr2:'hi', attr3:[5,4,3,2,1]}) to the C++ addon.

Until now, I've got around this by calling JSON.stringify() on my data object and then parsing the stringified JSON on the C++ side.

Ideally, I'd like to avoid copying data and just get a reference to the data object that I can access, or at least to copy it natively and avoid stringifying/parsing...

Any help would be appreciated!


Solution

  • You can allow your Node.js c++ addons to take arbitrary typed arguments, but you must check and handle the types explicitly. He is a simple example function that shows how to do this:

    void args(const Nan::FunctionCallbackInfo<v8::Value>& info) {
    
        int i = 0;
        while (i < info.Length()) {
            if (info[i]->IsBoolean()) {
                printf("boolean = %s", info[i]->BooleanValue() ? "true" : "false");
            } else if (info[i]->IsInt32()) {
                printf("int32 = %ld", info[i]->IntegerValue());
            } else if (info[i]->IsNumber()) {
                printf("number = %f", info[i]->NumberValue());
            } else if (info[i]->IsString()) {
                printf("string = %s", *v8::String::Utf8Value(info[i]->ToString()));
            } else if (info[i]->IsObject()) {
                printf("[object]");
                v8::Local<v8::Object> obj = info[i]->ToObject();
                v8::Local<v8::Array> props = obj->GetPropertyNames();
                for (unsigned int j = 0; j < props->Length(); j++) {
                    printf("%s: %s",
                           *v8::String::Utf8Value(props->Get(j)->ToString()),
                           *v8::String::Utf8Value(obj->Get(props->Get(j))->ToString())
                          );
                }
            } else if (info[i]->IsUndefined()) {
                printf("[undefined]");
            } else if (info[i]->IsNull()) {
                printf("[null]");
            }
            i += 1;
        }
    }
    

    To actually solve the problem of handling arbitrary arguments that may contain objects with arbitrary data, I would recommend writing a function that parses an actual object similar to how I parsed function arguments in this example. Keep in mind that you may need to do this recursively if you want to be able to handle nested objects within the object.