:
Value>& args) {
12. Isolate* isolate = args.GetIsolate();
13.
14. // Number 类型的声明
15. Local retval = v8:
:
Number:
:
New(isolate, 1000);
16.
17. // String 类型的声明
18. Local str = v8:
:
String:
:
NewFromUtf8(isolate, "Hello World!
");
19.
20. // Object 类型的声明
21. Local
:
Object:
:
New(isolate);
22. // 对象的赋值
23. obj->Set(v8:
:
String:
:
NewFromUtf8(isolate, "arg1"), str);
24. obj->Set(v8:
:
String:
:
NewFromUtf8(isolate, "arg2"), retval);
25.
26. // Function 类型的声明并赋值
27. Local tpl = v8:
:
FunctionTemplate:
:
New(isolate, MyFunction);
28. Local fn = tpl->GetFunction();
29. // 函数名字
30. fn->SetName(String:
:
NewFromUtf8(isolate, "theFunction"));
31. obj->Set(v8:
:
String:
:
NewFromUtf8(isolate, "arg3"), fn);
32.
33. // Boolean 类型的声明
34. Local flag = Boolean:
:
New(isolate, true);
35. obj->Set(String:
:
NewFromUtf8(isolate, "arg4"), flag);
36.
37. // Array 类型的声明
38. Local arr = Array:
:
New(isolate);
39. // Array 赋值
40. arr->Set(0, Number:
:
New(isolate, 1));
41. arr->Set(1, Number:
:
New(isolate, 10));
42. arr->Set(2, Number:
:
New(isolate, 100));
43. arr->Set(3, Number:
:
New(isolate, 1000));
44. obj->Set(String:
:
NewFromUtf8(isolate, "arg5"), arr);
45.
46. // Undefined 类型的声明
47. Local und = Undefined(isolate);
48. obj->Set(String:
:
NewFromUtf8(isolate, "arg6"), und);
49.
50. // null 类型的声明
51. Local null = Null(isolate);
52. obj->Set(String:
:
NewFromUtf8(isolate, "arg7"), null);
53.
54. // 返回给 JavaScript 调用时的返回值
55. args.GetReturnValue().Set(obj);
56.}
57.
58.void init(Local
59. NODE_SET_METHOD(exports, "getTestValue", Test);
60.}
61.
62.NODE_MODULE(returnValue, init)
所有的addon都需要一个初始化的函数,如下面的代码:
1.void Initialize(Local exports);
2.NODE_MODULE(module_name, Initialize)
Initialize 是初始化的函数,module_name 是编译后产生的二进制文件名,上述代码的模块名为returnValue。
上述代码通过node-gyp编译后(编译过程官方文档 C/C++Addons 有详细的介绍),可以通过如下的方式调用。
1.// returnValue.node 这个文件就是编译后产生的文件,通过 NODE_MODULE(returnValue, init) 决定的文件名
2.const returnValue = require('./build/Release/returnValue.node');
3.console.log(returnValue.getTestValue());
运行结果如下:
数据流向javaScript->C++
上面的demo展示了怎样在在C++定义JavaScript类型,数据的是从C++流向JavaScript,反过来数据也需要从javaScript流向C++,也就是调用C++函数的时候需要传入一些参数。
下面的代码展示了参数个数判断,参数类型判断,以及参数类型装换成V8类型的过程,包括基本类型以及Object,Array,Fuction。
1.#include
2.#include
3.#include
4.
5.using namespace v8;
6.using namespace std;
7.
8.void GetArgument(const FunctionCallbackInfo& args) {
9. Isolate* isolate = args.GetIsolate();
10.
11. // 参数长度判断
12. if (args.Length() < 2) {
13. isolate->ThrowException(Exception:
:
TypeError(
14. String:
:
NewFromUtf8(isolate, "Wrong number of arguments")));
15. return;
16. }
17.
18. // 参数类型判断
19. if (!
args[0]->IsNumber() || !
args[1]->IsNumber()) {
20. //抛出错误
21. isolate->ThrowException(Exception:
:
TypeError(
22. String:
:
NewFromUtf8(isolate, "argumnets must be number")));
23. }
24.
25. if (!
args[0]->IsObject()) {
26. printf("I am not Object\n");
27. }
28.
29. if (!
args[0]->IsBoolean()) {
30. printf("I am not Boolean\n");
31. }
32.
33. if (!
args[0]->IsArray()) {
34. printf("I am not Array\n");
35. }
36.
37. if (!
args[0]->IsString()) {
38. printf("I am not String\n");
39. }
40.
41. if (!
args[0]->IsFunction()) {
42. printf("I am not Function\n");
43. }
44.
45. if (!
args[0]->IsNull()) {
46. printf("I am not Null\n");
47. }
48.
49. if (!
args[0]->IsUndefined()) {
50. printf("I am not Undefined\n");
51. }
52.
53. // js Number 类型转换成 v8 Number 类型
54. Local value1 = Local:
:
Cast(args[0]);
55. Local value2 = Local:
:
Cast(args[1]);
56. double value = value1->NumberValue() + value2->NumberValue();
57.
58. // js String 类型转换成 v8 String 类型
59. Local str = Local:
:
Cast(args[2]);
60. String:
:
Utf8Value utfValue(str);
61. cout<62.
63. // js Array 类型转换成 v8 Array 类型
64. Local input_array = Local:
:
Cast(args[3]);
65. printf("%d, %f %f\n", input_array->Length(), input_array->Get(0)->NumberValue(), input_array->Get
(1)->NumberValue());
66.
67. // js Object 类型转换成 v8 Object 类型
68. Local obj = Local:
:
Cast(args[4]);
69.
70. // 根据 key 获取对象中的值
71. Local a = obj->Get(String:
:
NewFromUtf8(isolate, "a"));
72. Local b = obj->Get(String:
:
NewFromUtf8(isolate, "b"));
73.
74. // js Array 类型转换成 v8 Array 类型
75. Local c = Local:
:
Cast(obj->Get(String:
:
NewFromUtf8(isolate, "c")));
76. cout<NumberValue()<<" "<NumberValue()<77. printf("%d, %f %f\n", c->Length(), c->Get(0)->NumberValue(), c->Get
(1)->NumberValue());
78.
79. // js String 类型转换成 v8 String 类型
80. Local cString = Local:
:
Cast(c->Get
(2));
81. String:
:
Utf8Value utfValueD(cString);
82. cout<83.
84. // 根据 key 获取对象中的值
85. Local d = Local:
:
Cast(obj->Get(String:
:
NewFromUtf8(isolate, "d")));
86. Local dString1 = Local:
:
Cast(d->Get(String:
:
NewFromUtf8(isolate, "m")));
87. String:
:
Utf8Value utfValued1(dString1);
88. cout<89.
90. // 根据 key 获取对象中的值
91. Local dString2 = Local:
:
Cast(d->Get(String:
:
NewFromUtf8(isolate, "n")));
92. String:
:
Utf8Value utfValued2(dString2);
93. cout<94.
95. // js Booelan 类型转换成 v8 Boolean 类型
96. Local FlagTrue = Local:
:
Cast(args[5]);
97. cout<<"Flag:
"<BooleanValue()<98.
99. // js Function 类型转换成 v8 Function 类型
100. Local cb = Local:
:
Cast(args[8]);
101. const unsigned argc = 2;
102. Local argv[2];
103. argv[0] = a;
104. argv[1] = b;
105. cb->Call(Null(isolate), argc, argv);
106.
107. args.GetReturnValue().Set(value);
108.}
109.
110.void Init(Local exports, Local module) {
111. NODE_SET_METHOD(module, "exports", GetArgument);
112.}
113.
114.NODE_MODULE(argumentss, Init)
运行结果如下:
关于其他的类型,我这里就就不一一介绍,V8文档里面都有对应的API。
NAN
由于V8的API还没有彻底稳定下来,所以对于不同版本的Node.js类型相关的API会发生变化,而 NAN 帮我们做了封装,在编码的时候不需要关心版本问题,只需要引入相应的头文件即可。
引入头文件后,可以如下使用方式:
v8:
:
Local:
Primitive>Nan:
:
Undefined()
v8:
:
Local:
Primitive>Nan:
:
Null()
参考资料
∙TypeconversionsfromJavaScripttoC++inV8
∙nodeaddon
∙v8typesdocumentation
∙node-gyp
∙gypuserdocumentation
∙nan
【编辑推荐】
1.2016年12月编程语言排行榜:
C作为优秀老语言评级不足10%
2.Java程序员:
工作还是游戏该好好衡量一下
3.常见的JavaScript易错知识点整理
4..NETCore首例Office开源跨平台组件(NPOICore)
5.JavaScript中Write和Writeln的区别
6.能用HTML/CSS解决的问题就不要使用JS
7.Python爬虫爬取美剧网站