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

下载本文档

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

文档简介

NodeJS和C+之间的类型转换虽然在 Node.js 官方网站有很多的关于怎么使用这些 API 的文档,但是在 JavaScript 和 C+ 之间传递数据是一件非常麻烦的事情,C+ 是强类型语言(”1024” 是字符串类型而不是整数类型),而 JavaScript 却总是默认的帮我们做一些类型转换。作者:慎里来源:慎里|2016-12-07 11:23收藏 分享 我非常喜欢使用 Node.js,但是当涉及到计算密集型的场景时 Node.js 就不能够很好地胜任了。而在这样的情况下 C+ 是一个很好的选择,非常幸运 Node.js 官方提供了C/C+ Addons的机制让我们能够使用 V8 API 把 Node.js 和 C+ 结合起来。虽然在 Node.js 官方网站有很多的关于怎么使用这些 API 的文档,但是在 JavaScript 和 C+ 之间传递数据是一件非常麻烦的事情,C+ 是强类型语言(”1024” 是字符串类型而不是整数类型),而 JavaScript 却总是默认的帮我们做一些类型转换。JavaScript 的基本类型包括 String,Number,Boolean,null,undefined,V8 使用类继承的方式来定义这类型,这些类型都继承了Primitive类,而Primitive继承了Value,v8 也支持整型(包括Int32和Uint32),而所有的类型定义都可以从 V8类型文档中看到,除了基本的类型,还有 Object,Array,Map 等类型的定义。基本类型的继承关系如下图:在 V8 中所有 JavaScript 值都是被放在Local对象中,通过这个对象指定了 JavaScript 运行时的内存单元。下面这段代定义了一个Number类型的值,其中 Test 函数中声明的 isolate 变量代表着 V8 虚拟机中的堆内存,当创建新变量的时候就需要用到它,接下来的一行代码就通过 isolate 声明了一个Number类型的变量。1. #include2. #include3. 4. usingnamespacev8;5. 6. voidTest(constv8:FunctionCallbackInfo&args)7. Isolate*isolate=args.GetIsolate();8. /声明变量9. Localretval=v8:Number:New(isolate,1000);10. 11. 12. voidinit(Localexports,Localmodule)13. NODE_SET_METHOD(exports,getTestValue,Test);14. 15. 16. NODE_MODULE(returnValue,init)看了 V8类型 API 文档你会发现对于基本的 JavaScript 类型,只有变量的声明而没有变量的赋值。最初想可能觉得这个非常的奇怪,可是仔细想一想后发现这个是合理的。主要由以下几点原因: JavaScript 的基本类型是不可变类型,变量都是指向一个不可变的内存单元,var a = 10,则 a 指向的内存单元中包含的值为 5,重新赋值 a = 100,没有改变这个内存单元的值,而是使得 a 指向了另外一个内存单元,其中的值为 100。如果声明两个变量 x,y 的值都为 10,则他们指向的是同一个内存单元。 函数的传参都是传值,而不是传引用,当在 JavaScript 中调用 C+ 的函数时,如果参数是基本类型则每次都是把这个值拷贝过去,改变参数的值不会影响原来的值。 使用Local声明基本类型的变量都是对内存单元的引用,因为第一条原因不可能改变引用的值使其指向另外一个内存单元,因此不存在变量的重新赋值。数据流向 C+ - JavaScript下面 demo 定义了一些常用的 JavaScript 类型,包括基本类型的以及 Object, Array, Fuction。1. #include2. #include3. 4. usingnamespacev8;5. 6. voidMyFunction(constv8:FunctionCallbackInfo&args)7. Isolate*isolate=args.GetIsolate();8. args.GetReturnValue().Set(String:NewFromUtf8(isolate,HelloWorld!);9. 10. 11. voidTest(constv8:FunctionCallbackInfo&args)12. Isolate*isolate=args.GetIsolate();13. 14. /Number类型的声明15. Localretval=v8:Number:New(isolate,1000);16. 17. /String类型的声明18. Localstr=v8:String:NewFromUtf8(isolate,HelloWorld!);19. 20. /Object类型的声明21. Localobj=v8: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. Localtpl=v8:FunctionTemplate:New(isolate,MyFunction);28. Localfn=tpl-GetFunction();29. /函数名字30. fn-SetName(String:NewFromUtf8(isolate,theFunction);31. obj-Set(v8:String:NewFromUtf8(isolate,arg3),fn);32. 33. /Boolean类型的声明34. Localflag=Boolean:New(isolate,true);35. obj-Set(String:NewFromUtf8(isolate,arg4),flag);36. 37. /Array类型的声明38. Localarr=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. Localund=Undefined(isolate);48. obj-Set(String:NewFromUtf8(isolate,arg6),und);49. 50. /null类型的声明51. Localnull=Null(isolate);52. obj-Set(String:NewFromUtf8(isolate,arg7),null);53. 54. /返回给JavaScript调用时的返回值55. args.GetReturnValue().Set(obj);56. 57. 58. voidinit(Localexports,Localmodule)59. NODE_SET_METHOD(exports,getTestValue,Test);60. 61. 62. NODE_MODULE(returnValue,init)所有的 addon 都需要一个初始化的函数,如下面的代码:1. voidInitialize(Localexports);2. NODE_MODULE(module_name,Initialize)Initialize是初始化的函数,module_name是编译后产生的二进制文件名,上述代码的模块名为returnValue。上述代码通过 node-gyp 编译后(编译过程官方文档C/C+ Addons有详细的介绍),可以通过如下的方式调用。1. /returnValue.node这个文件就是编译后产生的文件,通过NODE_MODULE(returnValue,init)决定的文件名2. constreturnValue=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. #include2. #include3. #include4. 5. usingnamespacev8;6. usingnamespacestd;7. 8. voidGetArgument(constFunctionCallbackInfo&args)9. Isolate*isolate=args.GetIsolate();10. 11. /参数长度判断12. if(args.Length()ThrowException(Exception:TypeError(14. String:NewFromUtf8(isolate,Wrongnumberofarguments);15. return;16. 17. 18. /参数类型判断19. if(!args0-IsNumber()|!args1-IsNumber()20. /抛出错误21. isolate-ThrowException(Exception:TypeError(22. String:NewFromUtf8(isolate,argumnetsmustbenumber);23. 24. 25. if(!args0-IsObject()26. printf(IamnotObjectn);27. 28. 29. if(!args0-IsBoolean()30. printf(IamnotBooleann);31. 32. 33. if(!args0-IsArray()34. printf(IamnotArrayn);35. 36. 37. if(!args0-IsString()38. printf(IamnotStringn);39. 40. 41. if(!args0-IsFunction()42. printf(IamnotFunctionn);43. 44. 45. if(!args0-IsNull()46. printf(IamnotNulln);47. 48. 49. if(!args0-IsUndefined()50. printf(IamnotUndefinedn);51. 52. 53. /jsNumber类型转换成v8Number类型54. Localvalue1=Local:Cast(args0);55. Localvalue2=Local:Cast(args1);56. doublevalue=value1-NumberValue()+value2-NumberValue();57. 58. /jsString类型转换成v8String类型59. Localstr=Local:Cast(args2);60. String:Utf8ValueutfValue(str);61. coutstring(*utfValue)endl;62. 63. /jsArray类型转换成v8Array类型64. Localinput_array=Local:Cast(args3);65. printf(%d,%f%fn,input_array-Length(),input_array-Get(0)-NumberValue(),input_array-Get(1)-NumberValue();66. 67. /jsObject类型转换成v8Object类型68. Localobj=Local:Cast(args4);69. 70. /根据key获取对象中的值71. Locala=obj-Get(String:NewFromUtf8(isolate,a);72. Localb=obj-Get(String:NewFromUtf8(isolate,b);73. 74. /jsArray类型转换成v8Array类型75. Localc=Local:Cast(obj-Get(String:NewFromUtf8(isolate,c);76. coutNumberValue()NumberValue()Length(),c-Get(0)-NumberValue(),c-Get(1)-NumberValue();78. 79. /jsString类型转换成v8String类型80. LocalcString=Local:Cast(c-Get(2);81. String:Utf8ValueutfValueD(cString);82. coutstring(*utfValueD)endl;83. 84. /根据key获取对象中的值85. Locald=Local:Cast(obj-Get(String:NewFromUtf8(isolate,d);86. LocaldString1=Local:Cast(d-Get(String:NewFromUtf8(isolate,m);87. String:Utf8ValueutfValued1(dString1);88. coutstring(*utfValued1)endl;89. 90. /根据key获取对象中的值91. LocaldString2=Local:Cast(d-Get(String:NewFromUtf8(isolate,n);92. String:Utf8ValueutfValued2(dString2);93. coutstring(*utfValued2)endl;94. 95. /jsBooelan类型转换成v8Boolean类型96. LocalFlagTrue=Local:Cast(args5);97. coutFlag:BooleanValue()endl;98. 99. /jsFunction类型转换成v8Function类型100. Localcb=Local:Cast(args8);101. constunsignedargc=2;102. Localargv2;103. argv0=a;104. argv1=b;105. cb-Call(Null(isolate),argc,ar

温馨提示

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

评论

0/150

提交评论