Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to write the native module of node.js with CumberCraft +

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to write node.js native module using C _ Accord +". The explanation in this article is simple and clear, easy to learn and understand. Please follow the editor's train of thought to study and learn "how to use CAccord + to write node.js native module".

Hello World

Can not avoid vulgarity, the first to write a Hello World, after all, the programmer knows the first program is Hello World.

# include void hello (const v8::FunctionCallbackInfo & args) {v8::Isolate * isolate = args.GetIsolate (); auto message = v8::String::NewFromUtf8 (isolate, "Hello World!"); args.GetReturnValue (). Set (message);} void Initialize (v8::Local exports) {NODE_SET_METHOD (exports, "hello", hello);} NODE_MODULE (module_name, Initialize)

OK, this is the simplest HelloWorld. Let's name the file addon.cc, compile it with node-gyp, then import the module directly using require in our js file, and then we can call it.

Const myAddon = require ('. / build/Release/addon'); console.log (myAddon.hello ())

If there is no accident, Hello World! will be printed on the terminal.

Let's take a brief look at the code. The first line # include is the code that introduced the node.h header file into C++. The header file can be understood as an interface, in which we only define the interface method, which is not implemented, and then implemented through other files. The C++ linker is responsible for linking the two together.

Then a method hello () is defined with no return value. The method parameters are passed through const v8::FunctionCallbackInfo & args. Note that here we add a v8 using: prefix annotation, or you can use v8 directly at the beginning of the file; so you don't have to use this annotation every time.

V8::Isolate * isolate = args.GetIsolate (); here, we access the scope of javascript in the function.

Auto message = v8::String::NewFromUtf8 (isolate, "Hello World!"); we create a variable of type string, which assigns Hello World! And bind it to the scope.

We get the return value of our function through args.GetReturnValue ().

The Initialize () method is used to initialize the module method, binding the method to the method name of the module to be exported.

Finally, NODE_MODULE exports the module.

The above example is simple, if it is js code:

'use strict';let hello = function hello () {let message = "Hello World!"; return message;}; module.exports = {hello:hello}

All right, the first HelloWorld is over. There are a lot of online blog posts about the nodejs C++ module, which ends here. After reading it, he looked confused. What is this? I want to write another way to pass parameters and do simple operations on the parameters.

Sum (afort b)

Okay. So let's write another sum (arecom b) function, pass in two numeric type parameters, arecom b, and find the sum of the two arguments.

The code in js is as simple as the following:

Let sum = function (a typeof b) {if (typeof a = = 'number' & & typeof b = =' number') {return a + b;} else {throw new Error ('wrong parameter type');}}

So, how should C++ be written:

Void sum (const FunctionCallbackInfo & args) {Isolate * isolate = args.GetIsolate (); if (! args [0]-> IsNumber ()) {isolate- > ThrowException (v8::String::NewFromUtf8 (isolate, "args [0] must be a number")); return;} if (! args [1]-> IsNumber ()) {isolate- > ThrowException (v8::String::NewFromUtf8 (isolate (isolate, "args [1] must be a number"); return } args.GetReturnValue () .Set (args [0]-> NumberValue () + args [1]-> NumberValue ());}

First determine whether the two parameters are of type Number, and if not, throw an exception directly. If so, set the return value to the sum of the two parameters.

Here we do not directly use an args b as a parameter in the parameter list, but use the parameter object directly. This is similar to js, with the first parameter args [0] and the second parameter args [1].

Call IsNumber () to determine whether it is a numeric type. If not, throw a TypeError type error exception.

If the type is fine, use args [0]-> NumberValue () to get the numeric value of the parameter, then add it up, and assign the value to the return value.

You might ask, args [0] what is this? Where did its IsNumber () method come from? Where can I consult the documents?

This is actually the internal type of the V8 engine, which basically corresponds to the built-in object of js. You can consult the v8 type documentation.

The above picture is not very familiar, and the type system of js is very similar.

Js's Array,Date,Function,String and so on all inherit from Object, while inside the V8 engine, Object and Primitive inherit from the Value type.

The IsNumber () method here is a method of type Value. So apart from this method, is there any other way?

In the picture above, I only cut a small part of it, all of which can be consulted directly. Look, there are various methods to determine whether it is IsNumber () of numeric type, IsDate () of date type, IsArray () method of array, and so on.

The implementation of the interface of V8 is also very perfect, even developers who are not proficient in C++ can also follow suit to implement a simple module.

Args [0]-> NumberValue () returns a value of double. Yes, this is the double type in real C++, which can be added and subtracted directly. Similarly, there are BooleanValue () methods, and so on, which are methods used to get different types of values.

In the second example, we simply implement a sum () method, passing two parameters to sum. But what's involved here is only the value of an integer, so what if there are other types of values? Like an array.

SumOfArray (array)

Next, upgrade the method, pass an array, and then find the sum of all the values in the array. In js's words:

Let sumOfArray = function (array) {if (! Array.isArray (array)) {throw new Error ('parameter error, must be Array type');} let sum = 0; for (let item of array) {sum + = item;} return sum;}

The logic is simple: traverse the passed array and then add up all the items. The same is true of C++:

Void sumOfArray (const FunctionCallbackInfo & args) {Isolate * isolate = args.GetIsolate (); if (! args [0]-> IsArray ()) {isolate- > ThrowException (v8::String::NewFromUtf8 (isolate, "args [0] must be an Array")); return;} Local received_v8_obj = args [0]-> ToObject (); Local keys = received_v8_obj- > GetOwnPropertyNames (); int length = keys- > Length (); double sum = 0; for (int irid0) IGet (keys- > Get (I)-> NumberValue ();} args.GetReturnValue () .Set (sum);}

It's no problem to judge whether it is an array or not.

Then we define a received_v8_obj property of type Object and assign it to args [0]-> ToObject (). The ToObject () method is called here to convert it to an object.

Then call the object's GetOwnPropertyNames () method to get all the keys, and then get the value of the object based on the key for accumulation.

Why not just convert it to an array and then traverse it?

As we all know, an array in js is not a real array, but an object in essence. Its interior is stored by key-value pairs. So here too, the Value type does not provide a ToArray () method that converts directly to an array, but converts it to an Object object, which operates in the form of an object.

So what is the operation of the object? look at the document.

But you will find that V8 does have an Array class that inherits from the Object class. So what can Array do?

Just look at the documentation, which is pitifully rare:

Therefore, all operations on the array are converted to object operations.

CreateObj ()

When it comes to objects, let's write a method to create objects. Pass two parameters, a name and an age, to create an object that represents a person's name and age.

Void createObj (const FunctionCallbackInfo & args) {Isolate * isolate = args.GetIsolate (); Local obj = Object::New (isolate); obj- > Set (String::NewFromUtf8 (isolate, "name"), args [0]-> ToString ()); obj- > Set (String::NewFromUtf8 (isolate, "age"), args [1]-> ToNumber (); args.GetReturnValue (). Set (obj);}

There is basically nothing to say about this method, referring to the documentation.

Create an object through Object::New (isolate), then set two properties name,age, assign parameters to the two properties in turn, and then return the object.

If you write in js:

Let createObj = function (name,age) {let obj = {}; obj.name = name; obj.age = age; return obj;}

Callback

None of the above mentioned an important thing in js, the callback function. If a callback function is passed in the parameter, how do we execute it?

Let's take a simple example.

Let cb = function (typeof a! = = 'number' | | typeof b! = =' number') {throw new Error ('incorrect parameter type, can only be Number type');} if (typeof fn! = = 'function') {throw new Error (' parameter fn type, only Function type');} fn (acoreb);}

This example is very simple. We pass two numeric type parameters, a fn b and a callback function fn, and then call the fn callback function as an argument to the fn. Here we transfer the operation on aformab to the callback function. In the callback function, we can sum or quadrature, whatever you want.

In this example, what is not covered yet is how to call the callback function.

Code first:

Void cb (const FunctionCallbackInfo & args) {Isolate * isolate = args.GetIsolate (); if (! args [0]-> IsNumber ()) {isolate- > ThrowException (v8::Exception::TypeError (v8::String::NewFromUtf8 (isolate, "args [0] must be a Number") } if (! args [1]-> IsNumber ()) {isolate- > ThrowException (v8::Exception::TypeError (v8::String::NewFromUtf8 (isolate, "args [1] must be a Number");} if (! args [2]-> IsFunction ()) {isolate- > ThrowException (v8::String::NewFromUtf8 (isolate, "args [2] must be a Function") } Local jsfn = Local::Cast (args [2]); Local argv [2] = {Number::New (isolate,args [0]-> NumberValue ()), Number::New (isolate,args [1]-> NumberValue ())}; Local c = jsfn- > Call (Null (isolate), 2argv); args.GetReturnValue (). Set (c);}

The above three judge parameter types, skip.

We define a Function type property jsfn that casts args [2] to Function and assigns a value to jsfn.

Then define a parameter argv with two values, which are the numeric values of args [0] and args [1].

The callback function is then called through jsfn- > Call (Null (isolate), 2jargv).

Argv is an array, the number of which we specified when defining, 2.

The Call () method is the method that is called for the value of the function type.

Local

< Value >

| | Call (Handle) |

< Value >

Recv, int argc, Handle

< Value >

Argv [])

Looking up the documentation, you can see that the Call () method passes three parameters, the first parameter is the execution context, which is used to bind the this when the code is executed, the second parameter is the number of parameters, and the third is the parameter list, in the form of an array.

Thank you for your reading, the above is the content of "how to write node.js native modules using Cmax Cure +". After the study of this article, I believe you have a deeper understanding of the problem of how to write node.js native modules using Cmax Cure +, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report