The main content of the previous article stresses the use of CC ++ to implement Node. js module, This article further explores this issue. If you need it, you can refer to the warm-up to learn about it.
Remember this V8 online manual-http://izs.me/v8-docs/main.html.
Remember the last building. gyp file?
The Code is as follows:
{
"Targets ":[
{
"Target_name": "addon ",
"Sources": ["addon. cc"]
}
]
}
In this way, if there are a few more *. cc files:
"Sources": ["addon. cc", "myexample. cc"]
We separated the two steps last time. In fact, the configuration and compilation can be put together:
$ Node-gyp configure build
Have you reviewed? No ?!
Okay. Let's continue.
Table fan
Function Parameters
Now we have to talk about the parameters.
Let's assume that the add (a, B) function adds a and B to return the result, so write the function outer box first:
The Code is as follows:
# Include
Using namespace v8;
Handle Add (const Arguments & args)
{
HandleScope scope;
//... Come again!
}
Arguments
This is the function parameter. Let's take a look at v8's official manual reference.
• Int Length () const
• Local Operator [] (int I) const
We don't care about others. These two are important! One represents the number of parameters passed in the function, and the other is to access the nth parameter through the subscript index.
Therefore, for the above requirements, we can roughly understand that args. Length () is 2, and args [0] represents a and args [1] represents B. And we need to determine that the two numbers must be of the Number type.
Note: The index operator in brackets returns a Local value. That is, all types of base classes of Node. js. Therefore, if the input parameter type is not fixed, we must determine the parameter. This relates to some functions of this Value type.
• IsArray ()
• IsBoolean ()
• IsDate ()
• IsFunction ()
• IsInt32 ()
• IsNativeError ()
• IsNull ()
• IsNumber ()
• IsRegExp ()
• IsString ()
•...
I will not list them one by one. The rest will read the documents by myself. .:. Please wait (* 'hour') until then .:。
ThrowException
This is a function we will use. You can find it in the v8 document.
As the name suggests, an error is thrown. After executing this statement, it is equivalent to executing a throw () Statement in the local Node. js file. For example:
ThrowException (Exception: TypeError (String: New ("Wrong number of arguments ")));
It is equivalent to executing a Node. js:
Throw new TypeError ("Wrong number of arguments ");
Undefined ()
This function is also in the document.
Specifically, it is a null value, because some functions do not need to return specific values, or do not return values. In this case, Undefined () is used instead.
Cool!
After understanding the above points, I believe that you will soon be able to write the logic of a + B, and I will take Node. the code in the js official manual is copied to you once, even if it is done:
The Code is as follows:
# Include
Using namespace v8;
Handle Add (const Arguments & args)
{
HandleScope scope;
// Indicates that more than two parameters can be passed in, but we only use the first two
If (args. Length () <2)
{
// Throw an error
ThrowException (Exception: TypeError (String: New ("Wrong number of arguments ")));
// Return a null value
Return scope. Close (Undefined ());
}
// If one of the first two parameters is not a number
If (! Args [0]-> IsNumber () |! Args [1]-> IsNumber ())
{
// Throw an error and return a null value
ThrowException (Exception: TypeError (String: New ("Wrong arguments ")));
Return scope. Close (Undefined ());
}
// For more information, see v8.
// Http://izs.me/v8-docs/classv8_1_1Value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// The 'numbervalue' Function
Local Num = Number: New (args [0]-> NumberValue () + args [1]-> NumberValue ());
Return scope. Close (num );
}
Function success!
Finally, write the exported function at the end.
The Code is as follows:
Void Init (HandleExports)
{
Exports-> Set (String: NewSymbol ("add "),
FunctionTemplate: New (Add)-> GetFunction ());
}
NODE_MODULE (addon, Init)
After compilation, we can use it like this:
The Code is as follows:
Var addon = require ('./build/Release/addon ');
Console. log (addon. add (1, 1) + "B ");
You will see a 2b! Fail. Fail (please wait) then fail *。
Callback Function
In the previous chapter, we only talked about Hello world. In this chapter, the grandmother finds out his conscience and writes a callback function again.
By convention, we should first write the framework:
The Code is as follows:
# Include
Using namespace v8;
Handle RunCallback (const Arguments & args)
{
HandleScope scope;
//...
Return scope. Close (Undefined ());
}
Then we decided on its usage as follows:
Func (function (msg ){
Console. log (msg );
});
That is, it will input a parameter to the callback function. We suppose it is a string, and then we can view it through console. log.
First, you must have a string series.
Let's talk a little bit about it. feed it a string first. (√ ε :)
However, we have to make this string generic, because Node. js code is weak.
Local : New (String: New ("hello world "));
What? What is Local? ?
Let me talk about it for a moment. Refer to the reference documents from here and V8.
As shown in the document, Local Actually inherited from Handle I remember Handle in the previous chapter. This is now.
Next we will talk about Local.
Handle has two types: Local Handle and Persistent Handle. : Handle And Persistent : Handle , The former and Handle There is no difference that the life cycle is within the scope. While the latter's life cycle is out of scope, You need to manually call Persistent: Dispose to end its life cycle. That is to say, Local Handle is equivalent to allocating objects on the C ++ stack, while Persistent Handle is equivalent to allocating objects on the stack of C ++.
Then you need a parameter table series.
How can I obtain the command line parameters after the terminal command line calls C/C ++?
The Code is as follows:
# Include
Void main (int argc, char * argv [])
{
//...
}
By the way, argc is the number of command line parameters, and argv [] is the number of parameters. V8 uses a similar method to call the callback function of Node. js:
The Code is as follows:
V8EXPORT Local V8: Function: Call (Handle Recv,
Int argc,
Handle Argv []
);
~~ QAQ is stuck in HandleRecv !!! Continue writing tomorrow .~~
Well, I feel full of strength at the beginning of the new day. (^ O ^) Too many ☆too. * too .*・。
After my authentication (SegmentFault, StackOverflow, and a deduction group), I finally solved the meaning of the callback parameter of the above function.
The following two parameters are not much said. One is the number of parameters, and the other is an array of parameters. As for the first Handle parameterThe explanation of recv and StackOverflow is as follows:
It is the same as apply in JS. In JS, you do
The Code is as follows:
Var context = ...;
Cb. apply (context, [... args...]);
The object passed as the first argument becomes this within the function scope. More documentation on MDN. If you don't know JS well, you can read more about JS's this here: http://unschooled.org/2012/03/understanding-javascript-this/
-- From StackOverflow
In short, it specifies the this pointer of the called function. The Call usage is similar to bind (), call (), and apply () in JavaScript.
So what we need to do is first create the parameter table and then input the Call function for execution.
Step 1: display the conversion function because it is of the Object type:
Local Cb = Local : Cast (args [0]);
Step 2: Create a parameter table (array ):
Local Argv [argc] = {Local : New (String: New ("hello world "))};
Finally, call the Function Series
Call cb and pass the parameters in:
Cb-> Call (Context: GetCurrent ()-> Global (), 1, argv );
Here, the first parameter Context: GetCurrent ()-> Global () indicates obtaining the Global Context as the function's this; the second parameter is the number of parameter tables (after all, although Node. the js array has the Length attribute, but the length of the array in C ++ is actually unknown. You have to input a number to describe the length of the array ); the last parameter is the parameter table we just created.
End file Series
I believe everyone is familiar with this step, that is, to write the function, put it in the export function, and finally declare it.
Let me release the Code directly, or directly go to the Node. js document to view it.
The Code is as follows:
# Include
Using namespace v8;
Handle RunCallback (const Arguments & args)
{
HandleScope scope;
Local Cb = Local : Cast (args [0]);
Const unsigned argc = 1;
Local Argv [argc] = {Local : New (String: New ("hello world "))};
Cb-> Call (Context: GetCurrent ()-> Global (), argc, argv );
Return scope. Close (Undefined ());
}
Void Init (HandleExports, HandleModule)
{
Module-> Set (String: NewSymbol ("exports "),
FunctionTemplate: New (RunCallback)-> GetFunction ());
}
NODE_MODULE (addon, Init)
Well done! Go to the remaining steps. As for calling this function in Js, I have mentioned it before.
Fan Wai
Well, I feel that my study notes are getting more and more written ~
Let's write it here today. I raised my posture when I wrote my study notes, for example, the parameter meaning of the Call function.
If you think this series of study notes is helpful to you, come and work with me ~ σ>-(〃 ° ω ° variance 〃)♡→