NodeJS和C++之间的类型转换分析_第1页
NodeJS和C++之间的类型转换分析_第2页
NodeJS和C++之间的类型转换分析_第3页
NodeJS和C++之间的类型转换分析_第4页
NodeJS和C++之间的类型转换分析_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、NodeJS和C+之间的类型转换虽然在Node.js 官方网站有很多的关于怎么使用这些API的文档,但是在JavaScript和C+之间传递数据是一件非常麻烦的事情,C+是强类型语言 1024 是字符串类型而不是整数类型,而 JavaScript却总是默认的帮我们做一些类型转换. 慎里来源: 慎里|2021-12-07 11:23收藏分享我非常喜欢使用Node.js,但是当涉及到计算密集型的场景时Node.js就不能够很好地胜任了.而在这样的情况下C+是一个很好的选择,非常幸运Node.js官方提供了C/C+ Addons的机制让我们能够使用V8 API把Node.js 和C+结合起来.虽然在

2、Node.js官方网站有很多的关于怎么使用这些API的文档,但是在JavaScript和C+之间传递数据是一件非常麻烦的事情,C+是强类型语言 1024是字符串类型而不是整数类型,而 JavaScript却总是默认的帮我们做一些类型转换.JavaScript 的根本类型包括 String ,Number ,Boolean ,null,undefined ,V8使用类继承的方式来定义这类型,这些类型都继承了Primitive 类,而Primitive 继承了 Value,v8也支持整型包括Int32 和Uint32 ,而所有 的类型定义都可以从V8类型文档中看到,除了根本的类型,还有Object

3、,Array,Map等类型的定义.根本类型的继承关系如下列图:DataValue在V8中所有JavaScript值都是被放在Local对象中,通过这个对象指定了JavaScript运行时的内存单元.F面这段代定义了一个 Number类型的值,其中Test函数中声明的isolate变量代表着 V8 虚拟机中的堆内存,当创立新变量的时候就需要用到它,接下来的一行代码就通过isolate声明了一个Number类型的变量.1. #include <node.h>2. #include <v8.h>3.3. using namespace v8;5.4. void Test( c

4、onst v8:FunctionCallbackInfo<v8:Value>& args) 5. Isolate* isolate = args.GetIsolate();6. / 声明变量7. Local<Number> retval = v8:Number:New(isolate, 1000 );8. 11.12. void init(Local <Object> exports, Local<Object> module) 13. NODE_SET_METHOD(exports, "getTestValue" ,

5、 Test);14. 15.16. NODE_MODULE(returnValue, init)看了 V8 类型 API 文档 你会发现对于根本的 JavaScript 类型,只有变量的声 明而没有变量的赋值. 最初想可能觉得这个非常的奇怪, 可是仔细想一想后发现 这个是合理的.主要由以下几点原因:? JavaScript 的根本类型是不可变类型,变量都是指向一个不可变的内存单元,var a = 10,那么a指向的内存单元中包含的值为 5,重新赋值a = 100,没有改变这个内存单元的值,而是使得 a 指向了另外一个内存单元,其中 的值为 100.如果声明两个变量 x, y 的值都为 10,那

6、么他们指向的是同一个内存单元? 函数的传参都是传值, 而不是传引用, 当在 JavaScript 中调用 C+ 的函 数时,如果参数是根本类型那么每次都是把这个值拷贝过去,改变参数的值 不会影响原来的值.? 使用 Local<Value> 声明根本类型的变量都是对内存单元的引用, 由于第一 条原因不可能改变引用的值使其指向另外一个内存单元,因此不存在变量 的重新赋值.数据流向 C+ -> JavaScript下面 demo 定义 了一 些常 用 的 JavaScript 类型,包括根本 类型的以及Object, Array, Fuction .1. #include <

7、node.h>2. #include <v8.h>3.4. using namespace v8;5.6. void MyFunction( const v8:FunctionCallbackInfo<Value>& args) 7. Isolate* isolate = args.GetIsolate();8. args.GetReturnValue().Set(String:NewFromUtf8(isolate, "Hello World!" );9. 10.9. void Test( const v8:FunctionCallb

8、ackInfo<v8:Value>& args) 10. Isolate* isolate = args.GetIsolate();13.14. / Number 类型的声明1000 );"Hello World!" );15. Local<Number> retval = v8:Number:New(isolate,16.17. / String 类型的声明18. Local<String> str = v8:String:NewFromUtf8(isolate,19.20. / Object 类型的声明21. Local<

9、;Object> obj = v8:Object:New(isolate);22. / 对象的赋值23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57."arg1" ), str);"arg2" ), retval);obj->Set(v8:String:NewFromUtf8(isolate,obj->Set(v8:String:NewFromUtf8(isolate, / Fun

10、ction 类型的声明并赋值Local<FunctionTemplate> tpl = v8:FunctionTemplate:New(isolate, MyFuncti on);Local<Function> fn = tpl->GetFunction();/ 函数名字fn->SetName(String:NewFromUtf8(isolate,obj->Set(v8:String:NewFromUtf8(isolate,"theFunction" );"arg3" ), fn);/ Boolean 类型的声明

11、Local<Boolean> flag = Boolean:New(isolate,true );obj->Set(String:NewFromUtf8(isolate, "arg4" ), flag);/ Array 类型的声明Local<Array> arr = Array:New(isolate);/ Array 赋值arr->Set( 0, Number:New(isolate, 1); arr->Set( 1, Number:New(isolate, 10);arr->Set( 2, Number:New(isola

12、te, 100 );arr->Set( 3, Number:New(isolate, 1000 ); obj->Set(String:NewFromUtf8(isolate, "arg5" ), arr);/ Undefined 类型的声明Local<Value> und = Undefined(isolate); obj->Set(String:NewFromUtf8(isolate, "arg6" ), und);/ null 类型的声明Local<Value> null = Null(isolate); o

13、bj->Set(String:NewFromUtf8(isolate, "arg7" ), null );/ 返回给 JavaScript 调用时的返回值args.GetReturnValue().Set(obj);58. void init(Local <Object> exports, Local<Object> module) 59. NODE_SET_METHOD(exports, "getTestValue" , Test);60. 61.62. NODE_MODULE(returnValue, i nit)所有的

14、addon都需要一个初始化的函数,如下面的代码:1. void Initialize(Local<Object> exports);2. NODE_MODULE(module_name, Initialize)Initialize 是初始化的函数,module_name是编译后产生的二进制文件名,上述 代码的模块名为returnValue.上述代码通过node-gyp 编译后(编译过程官方文档C/C+ Addo ns有详细的介绍),可以通过如下的方式调用.1. / returnValue.node这个文件就是编译后产生的文件,通过 NODE_MODULE(returnValue,

15、i nit)决定的文件名2. const returnValue = require( './build/Release/returnValue.node');3. con sole .lo g(retur nV alue.getTestValue();运行结果如下:sivision:test$ node test.js argl::1 Hello World!1farg2:100Otarg3:Function: theFunction,arg4:true,argSi:lf 10, 100, 1000 Farg6:undefined,arg7:null 数据流向 javaScr

16、ipt -> C+上面的 demo 展示了怎样在在C+ 定义 JavaScript 类型,数据的是从C+ 流向 JavaScript ,反过来数据也需要从 javaScript 流向 C+ ,也就是 调用 C+ 函数的时候需要传入一些参数.下面的代码展示了参数个数判断,参数类型判断,以及参数类型装换成 V8 类 型的过程,包括根本类型以及 Object, Array, Fuction .1. #include <node.h>2. #include <v8.h>3. #include <iostream>4.5. using namespace v8;

17、6. using namespace std;7.8. void GetArgument( const FunctionCallbackInfo<Value>& args) 9. Isolate* isolate = args.GetIsolate();10.11. / 参数长度判断12. if (args.Length() < 2) 11. isolate->ThrowException(Exception:TypeError(12. String:NewFromUtf8(isolate,"Wrong number of arguments"

18、; );13. 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 Objectn"

19、; );27. 28.29. if (!args 0->IsBoolean() 30. printf( "I am not Booleann" );31. 32.33. if (!args 0->IsArray() 34. printf( "I am not Arrayn" );35. 36.37. if (!args 0->IsString() 38. printf( "I am not Stringn" );39. 40.41. if (!args 0->IsFunction() 42. printf( &

20、quot;I am not Functionn" );43. 44.45. if (!args 0->IsNull() 46. printf( "I am not Nulln" );47. 48.49. if (!args 0->IsUndefined() 50. printf( "I am not Undefinedn" );51. 52.53. / js Number 类型转换成 v8 Number 类型54. Local<Number> value1 = Local<Number>:Cast(args

21、0);55. Local<Number> value2 = Local<Number>:Cast(args 1);56. double value = value1->NumberValue() + value2->NumberValue();57.58. / js String 类型转换成 v8 String 类型59. Local<String> str = Local<String>:Cast(args2);60. String:Utf8Value utfValue(str);61. cout<<string(*ut

22、fValue)<<endl;62.63. / js Array 类型转换成 v8 Array 类型64. Local<Array> input_array = Local<Array>:Cast(args3);0 )->NumberVa65. printf( "%d, %f %fn" , input_array->Length(), input_array->Get( lue(), input_array->Get( 1)->NumberValue();#.67./ js Object 类型转换成 v8 Ob

23、ject 类型68.Local<Object> obj = Local<Object>:Cast(args 4);69.70./ 根据 key 获取对象中的值71.Local<Value> a = obj->Get(String:NewFromUtf8(isolate,"a");72.Local<Value> b = obj->Get(String:NewFromUtf8(isolate,"b");73.74./ js Array 类型转换成 v8 Array 类型75.Local<Arr

24、ay> c = Local<Array>:Cast(obj->Get(String:NewFromUtf8(isolate,"c");76.cout<<a->NumberValue()<< " " <<b->NumberValue()<<endl;77.printf( "%d, %f %fn" , c->Length(), c->Get( 0)->NumberValue(), c->Get(mberValue();78.79./

25、 js String 类型转换成 v8 String 类型80.Local<String> cString = Local<String>:Cast(c->Get(2);81.String:Utf8Value utfValueD(cString);82.cout<<string(*utfValueD)<<endl;83.84./ 根据 key 获取对象中的值85.Local<Object> d = Local<Object>:Cast(obj->Get(String:NewFromUtf8(isolate, &

26、quot;d");86.Local<String> dString1 = Local<String>:Cast(d->Get(String: solate, "m" );:NewFromUtf8(i87.String:Utf8Value utfValued1(dString1);88.cout<<string(*utfValued1)<<endl;89.90./ 根据 key 获取对象中的值91.Local<String> dString2 = Local<String>:Cast(d-

27、>Get(String: solate, "n" );:NewFromUtf8(i92.String:Utf8Value utfValued2(dString2);93.cout<<string(*utfValued2)<<endl;94.95./ js Booelan 类型转换成 v8 Boolean 类型96.Local<Boolean> FlagTrue = Local<Boolean>:Cast(args5);97.cout<< "Flag: " <<FlagTrue->BooleanValue()<<endl;1)->Nu#.99. / js Function 类型转换成 v8 Function 类型100. Local<Function> cb = Local<Function>:Cast(args8);101. const unsigned argc = 2;102. Local<

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论