从v8到C++的数据类型转换

这里说的数据类型指的是基本数据类型(数值、字符、布尔),对象类型实际上也只是基本类型的结构化堆叠而已,对于数据类型的转换我们只要考虑基本类型就够了。而在V8中所有数据类型都继承于Value类的,我们只要知道Value实例如何转换成C++基本类型即可。
  Value类的成员函数中直接就提供了数值型和布尔型的转换函数,直接调用它就可以得到相应的值。但是对于字符串就麻烦了,由于有编码问题,没有在Value的成员函数中封装,而是在String的静态成员下添加了几个类成员来实现字符串的转换。
  首先看 Value类 ,里面提供了一大堆的方法,不过基本都是判断类型和内部装换用的。但其中也有几个外部转换的方法:
     bool BooleanValue()
     double NumberValue()
     int32_t Int32Value()
     int64_t IntegerValue()
     uint32_t Uint32Value()
  在Value实例上直接调用这些方法就可以得到相应的C++基本类型。对于字符串,我们再看看 String类 下面用于抽出数据的静态类:
     class String::AsciiValue()
     class String::Utf8Value()
     class String::Value()
  从名字就可以大概看出他们的功能。AsciiValue是直接使用ASCII字符,这意味着遇到多字节字符时候只取第一个字节,后面的抛弃。Utf8Value是把字符串以UTF-8的字符集导出,字母占一个字节,汉字占三个字节。最后一个Value是使用Unicode导出数据,字母和汉字都占两个字节。这东西测试起来有点麻烦了,因为控制台输出字符串的默认编码是ANSI,以上三种编码方式抽取的数据直接输出到控制台都无法显示汉字。所以我在后面的测试中不直接输出字符串,而是把他们的字节逐个输出来。
  然而,这三个东西是类啊,又不是函数,就算创建了这些类的实例又要怎么转换成C++的字符串格式呢?实际上这三个类的实例的数据部分就是一个字符串指针,已经没有多余的数据了,我们只要取出它指向的字符串即可。注意这里的字符串指针(string*),而不是字符指针(char*)。所以使用“*”运算符来取它们的目标对象才会得到一个字符串(string)。或者说它原本是指向字符指针的指针(char**),使用“*”运算符把它还原成字符指针(char*)。
  下面是代码:
//\node_modules\test.cpp#include <node.h>#include <iostream>#pragma comment(lib,"node.lib")using namespace v8;using namespace std;Handle<Value> f(const Arguments &args){ //双精度浮点数 cout<<args[0]->NumberValue()<<endl; //64位整数 cout<<args[0]->IntegerValue()<<endl; //32位整数 cout<<args[0]->Int32Value()<<endl; //32位无符号整数 cout<<args[0]->Uint32Value()<<endl; //布尔 cout<<args[2]->BooleanValue()<<endl; //UTF-8字符串 String::Utf8Value s1(args[1]); byte *v1=(byte*)*s1; cout<<(int)v1[0]<<" "<<(int)v1[1]<<" "<<(int)v1[2]<<endl; //ASCII字符串 String::AsciiValue s2(args[1]); byte *v2=(byte*)*s2; cout<<(int)v2[0]<<endl; //Unicode字符串 String::Value s3(args[1]); byte *v3=(byte*)*s3; cout<<(int)v3[0]<<" "<<(int)v3[1]<<" "<<endl; //该函数返回一个undefined return Undefined();};void main(Handle<Object> exports){ //把C++中的函数f做成JavaScript函数 auto js_f=FunctionTemplate::New(f)->GetFunction(); //把刚做成的函数赋到模块接口对象的f属性上 exports->Set(String::NewSymbol("f"),js_f);}NODE_MODULE(test,main) //\test.njsvar test=require('test');console.log(test.f(3,"钴",true));
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值