c++node.jsv8node.js-addon

Node.js Addon cannot convert arguments


I'm making String Transformation library using Node.js c++ Addons.

I know I can easily make this library with JavaScript, but I need to do it with Node.js c++ Addons.

According to this answer Converting from v8::Arguments to C++ Types. I have checked This answer but its returns the same error

So I declared void uppercase to transform some String to Uppercase.

But there is an Error

D:\transformer\src\transformer.cc(30): error C2664: 'std::string Transformation::toUpperCase(std::string)': cannot convert argument 1 from 'v8::Local<v8::String>' to 'std::string'  [D:\transformer\build\transformer.vcxproj]

I tried to solve that but failed because I'm new to c++ addons. I also checked that error code C2664 which doesn't solve my problem.

transformer.cc

// transformer.cc
#include <node.h>
#include <iostream>
#include <algorithm>

using namespace v8;
using namespace std;

namespace Transformations {

    string toUpperCase(string str) {
        transform(str.begin(), str.end(), str.begin(), ::toupper);
        return str;
    }

}

namespace Transformer {

    void uppercase(const FunctionCallbackInfo<Value>& args) {
        Isolate *isolate = args.GetIsolate();
        
        Local<String> str = Local<String>::Cast(args[0]);

        if(!args[0]->IsString()) {
            isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments")));
            return;
        }

        args.GetReturnValue().Set(Transformations::toUpperCase(str));
    }

    void lowercase(const FunctionCallbackInfo<Value>& args) { }

    void capitalize(const FunctionCallbackInfo<Value>& args) { }

    void reverse(const FunctionCallbackInfo<Value>& args) { }

    void init(Local<Object> exports) {
        NODE_SET_METHOD(exports, "uppercase", uppercase);
        NODE_SET_METHOD(exports, "lowercase", lowercase);
        NODE_SET_METHOD(exports, "capitalize", capitalize);
        NODE_SET_METHOD(exports, "reverse", reverse);
    }

    NODE_MODULE(transformer, init)

}

test.js

const transformer = require('bindings')('transformer');

console.log(transformer.uppercase("Dinindu"));


Solution

  • I found the solution here, The Native Abstractions (nan) solved my problem.

    1. First add this code to the binding.gyp file under the targets

    "include_dirs" : ["<!(node -e \"require('nan')\")"]
    

    2. After installing nan, import it by adding this line at the head of transformer.cc

    #include <nan.h>
    

    3. Now, change our uppercase function a bit:

    void uppercase(const FunctionCallbackInfo<Value>& args) {
        Isolate *isolate = args.GetIsolate();
    
        v8::String::Utf8Value value(args[0]->ToString());
        std::string name = std::string(*value);
        std::string uppercased_name = Transformations::toUpperCase(name);
    
        if(!args[0]->IsString()) {
            isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments")));
            return;
        }
    
        args.GetReturnValue().Set(Nan::New(uppercased_name).ToLocalChecked());
    }