Type conversions between Node. JS and C + +

Source: Internet
Author: User

I'm very fond of using Node. JS development, But when it comes to compute-intensive scenarios, Node. JS is not very well Qualified. And in this case C + + is a good choice, very fortunate that Node. JS officially provides a mechanism for c/+ + Addons that allows us to use the V8 API to combine Node. JS with C + +.

While there are a lot of documents on how to use these APIs on the Node. JS website, It's a hassle to pass data between JavaScript and C + +, which is a strongly typed language ("1024" is a string type instead of an integer type), and JavaScript It's always the default to help us do some type conversions.

The basic types of JavaScript include the way String,number,boolean,null,undefined,v8 uses class inheritance to define this type, which inherit the Primitive class, and Primitive inherits Value. V8 also supports integer types (including Int32 and Uint32), and all type definitions can be seen from the V8 type document, in addition to the basic types, as well as the definition of object,array,map.

Basic types of inheritance are as Follows:

All JavaScript values in V8 are placed in the Local object, which specifies the memory unit of the JavaScript Runtime.

The following generation defines a value of type number, where the isolate variable declared in the Test function represents the heap memory in the V8 virtual machine, which is needed when creating a new variable, and the next line of code declares a variable of type number by Isolate.

#include

#include

UsingNamespace v8;

void Test (const V8::functioncallbackinfo & Args) {

isolate* Isolate = args. Getisolate ();

declaring variables

Local retval = v8::number::new (isolate, 1000);

}

void init (local exports, local Module) {


Node_set_method (exports, "gettestvalue", Test);

}

Node_module (returnvalue, Init)

Look at the V8 type API documentation you will find that for basic JavaScript types, only the variables are declared and no variables are Assigned. I thought it might seem strange at first, but it's reasonable to think it over. Mainly by the following reasons:

The basic type of JavaScript is the immutable type, the variable is pointing to an immutable memory unit, var a = 10, a point to the memory unit contains a value of 5, re-assigned a = 100, does not change the value of the memory unit, but instead of a point to another memory unit, where the value is 100. If the value of two variables x, y is declared to be 10, they point to the same memory unit.

The Function's argument is a pass value, not a reference, when invoking a C + + function in JavaScript, if the argument is the base type, each time the value is copied past, changing the value of the parameter does not affect the original Value.

A variable that uses the Local declaration base type is a reference to a memory unit because the first reason is not likely to change the value of the reference so that it points to another memory unit, so there is no re-assignment of the Variable.

Data flow to C + + JavaScript

The following demo defines some common JavaScript types, including the basic type and Object, Array, Fuction.

#include

#include

UsingNamespace v8;

void MyFunction (const V8::functioncallbackinfo & Args) {

isolate* Isolate = args. Getisolate ();

Args. Getreturnvalue (). Set (string::newfromutf8 (isolate, "Hello world!"));

}

void Test (const V8::functioncallbackinfo & Args) {

isolate* Isolate = args. Getisolate ();

Declaration of Number Type

Local retval = v8::number::new (isolate, 1000);

Declaration of type String

Local str = V8::string::newfromutf8 (isolate, "Hello world!");

Declaration of type Object

Local obj = v8::object::new (isolate);


Assigning values to Objects

Obj->set (v8::string::newfromutf8 (isolate, "arg1"), str);

Obj->set (v8::string::newfromutf8 (isolate, "arg2"), retval);

Declaration of a Function type and assignment of a value

Local TPL = v8::functiontemplate::new (isolate, MyFunction);

LOCAL fn = tpl->getfunction ();

Function name

Fn->setname (string::newfromutf8 (isolate, "thefunction"));

Obj->set (v8::string::newfromutf8 (isolate, "arg3"), fn);

Declaration of a Boolean type

Local flag = boolean::new (isolate, true);

Obj->set (string::newfromutf8 (isolate, "arg4"), flag);

Declaration of the Array type

Local arr = array::new (isolate);

Array Assignment

Arr->set (0, number::new (isolate, 1));

Arr->set (1, number::new (isolate, 10));

Arr->set (2, number::new (isolate, 100));

Arr->set (3, number::new (isolate, 1000));

Obj->set (string::newfromutf8 (isolate, "arg5"), arr);

Declaration of the Undefined type

Local und = Undefined (isolate);

Obj->set (string::newfromutf8 (isolate, "arg6"), und);

Declaration of a null type

Local NULL = NULL (isolate);

Obj->set (string::newfromutf8 (isolate, "arg7"), null);

Return value returned to the JavaScript call

Args. Getreturnvalue (). Set (obj);

}

void init (local exports, local Module) {


Node_set_method (exports, "gettestvalue", Test);

}

Node_module (returnvalue, Init)

All addon require an initialized function, such as the following code:


void Initialize (Local exports);


Node_module (module_name, Initialize)

Initialize is the initialized function, module_name is the binary file name generated after compilation, the module name of the above code is Returnvalue.


The above code is compiled by Node-gyp (detailed description of the Compiler's Official document C + + Addons), which can be called in the following way.


Returnvalue.node This file is the file that is generated after the compilation, and is determined by Node_module (returnvalue, Init)

Const RETURNVALUE = require ('./build/release/returnvalue.node ');

Console.log (returnvalue.gettestvalue ());

The results of the operation are as Follows:


Data flow to JavaScript-c + +

The demo above shows how to define the JavaScript type in C + +, The data is flowing from C + + to javascript, and the data also needs to flow from JavaScript to C + +, that is, when calling C + + functions, you need to pass in some Parameters.

The following code shows the number of arguments, the type of argument, and the process of replacing the parameter type with the V8 type, including the base type and Object, Array, Fuction.

#include

#include

#include


UsingNamespace v8;

UsingNamespace std;


void GetArgument (const Functioncallbackinfo & Args) {

isolate* Isolate = args. Getisolate ();


Parameter length judgment

If (args. Length () < 2) {

Isolate->throwexception (exception::typeerror (

String::newfromutf8 (isolate, "wrong Number of arguments"));

Return

}


Parameter type judgment

If (!args[0]->isnumber () | |!args[1]->isnumber ()) {

Throw error

Isolate->throwexception (exception::typeerror (

String::newfromutf8 (isolate, "argumnets must be number"));

}


If (!args[0]->isobject ()) {

printf ("I am not object\n");

}


If (!args[0]->isboolean ()) {

printf ("I am not boolean\n");

}


If (!args[0]->isarray ()) {

printf ("I am not array\n");

}


If (!args[0]->isstring ()) {

printf ("I am not string\n");

}


If (!args[0]->isfunction ()) {

printf ("I am not function\n");

}


If (!args[0]->isnull ()) {

printf ("I am not null\n");

}


If (!args[0]->isundefined ()) {

printf ("I am not undefined\n");

}


JS number type converted to V8 number type

Local value1 = local:: Cast (args[0]);

Local value2 = local:: Cast (args[1]);

Double value = Value1->numbervalue () + value2->numbervalue ();


JS string type converted to V8 string type

Local str = local:: Cast (args[2]);

String::utf8valueutfvalue (str);

cout<<><>< p=""><><>


JS array type converted to V8 array type

Local Input_array = local:: Cast (args[3]);

printf ("%d,%f%f\n", input_array->length (), input_array->get (0)->numbervalue (), input_array->get (1)- >numbervalue ());


JS object type converted to V8 object type

Local obj = local:: Cast (args[4]);



Gets the value from the object according to key

Local a = Obj->get (string::newfromutf8 (isolate, "a"));

Local B = Obj->get (string::newfromutf8 (isolate, "b"));


JS array type converted to V8 array type

Local c = local:: Cast (obj->get (string::newfromutf8 (isolate, "c")));

cout< numbervalue () << "" "< numbervalue () <<>< p=""><>

printf ("%d,%f%f\n", c->length (), c->get (0)->numbervalue (), c->get (1)->numbervalue ());


JS string type converted to V8 string type

Local cString = local:: Cast (c->get (2));

String::utf8valueutfvalued (cString);

cout<<><>< p=""><><>


Gets the value from the object according to key

Local d = local:: Cast (obj->get (string::newfromutf8 (isolate, "d")));


Local dString1 = local:: Cast (d->get (string::newfromutf8 (isolate, "m")));

String::utf8valueutfvalued1 (dString1);

cout<<><>< p=""><><>


Gets the value from the object according to key

Local dString2 = local:: Cast (d->get (string::newfromutf8 (isolate, "n")));

String::utf8valueutfvalued2 (dString2);

cout<<><>< p=""><><>


JS Booelan type converted to V8 Boolean type

Local flagtrue = local:: Cast (args[5]);

cout<< "Flag:" < Booleanvalue () <<>< p=""><>


JS function type converted to V8 function type

Local CB = local:: Cast (args[8]);

Const unsigned ARGC = 2;

Local argv[2];

argv[0] = a;

argv[1] = b;

Cb->call (Null (isolate), argc, argv);


Args. Getreturnvalue (). Set (value);

}


void Init (local exports, local Module) {


Node_set_method (module, "exports", getargument);

}


Node_module (argumentss, Init)

After compiling through node-gyp, it can be called in the following way.


Const GETARGUMENTS = require ('./build/release/arguments ');


Console.log (getarguments (2, 3, ' Hello Arguments ', [1, 2, 3], {

a:10,

b:100,

C: [23, 22, "i am 33"],

D: {m: ' I am a ', n: ' I am 23 '}

}, true, null, undefined,

function MyFunction (.... Args) {

Console.log (' I am function! ');

Console.log (... args);

Console.log (' I am function! ');

}));

The results of the operation are as Follows:


As for the other types, I will not introduce them here, V8 documents have corresponding APIS.

NAN

Since the API for V8 has not been completely stabilized, the APIs associated with different versions of Node. JS types change, and Nan helps us encapsulate the code without needing to worry about the version issue, just introduce the appropriate header File.

After introducing the header file, you can use the following methods:

v8::localnan::undefined () V8::localnan::null ()


source: Bole Online


Type conversions between Node. JS and C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.