NodeJS - V8和JS的参数类型转换

参考文章

http://taobaofed.org/blog/2016/09/20/type-casts-between-node-and-cpp/

https://nodejs.org/dist/latest-v8.x/docs/api/addons.html


Addons的机制,允许我们在js和c++互相调用,经常会传递参数或者返回结果,这时候需要做类型转换。包括js -> v8, 和 V8-> js。

1、js -> v8方向

#include <node.h>
#include <v8.h>
#include <iostream>

using namespace v8;
using namespace std;

void GetArguments(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();

    printf("Hello GetArguments\n");

    if (args.Length() == 0) {
        isolate->ThrowException(Exception::TypeError(
                String::NewFromUtf8(isolate, "Wrong number of arguements")));
        return;
    }

    if (!args[0]->IsNumber()) {
        printf("I am not Number \n");
        return;
    }

    Local<Number> value1 = Local<Number>::Cast(args[0]);
    cout << "first argument = " << value1->NumberValue() << endl;

    Local<String> value2 = Local<String>::Cast(args[1]);
    String::Utf8Value utfValue(value2);
    cout << "second argument = " << string(*utfValue) << endl;
}

void init(Local<Object> exports) {
    NODE_SET_METHOD(exports, "getArgs", GetArguments);
}

NODE_MODULE(addon, init)

执行 node-gyp configure build,编译cc文件。

在js文件中测试,

const addon =  require('./build/Release/addon-test');

console.log("This should be eight:" + JSON.stringify(addon.getArgs(12, "Hello")));
day
打印为:

Hello GetArguments
first argument = 12
second argument = Hello

可以看到,js中的参数已经传递到了v8的c++代码,并转换成了V8的类型。


2. v8->js方向

#include <node.h>
#include <v8.h>

using namespace v8;

void MyFunction(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hello MyFunction!"));
}

void TestValue(const v8::FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();

    printf("Hello TestValue \n");

    Local<Object> obj = Object::New(isolate);

    // Number type
    Local<Number> number = Number::New(isolate, 100);
    obj->Set(String::NewFromUtf8(isolate, "numValue"), number);

    // String type
    Local<String> str = String::NewFromUtf8(isolate, "Hello world!");
    obj->Set(String::NewFromUtf8(isolate, "strValue"), str);

    // Boolean type
    Local<Boolean> flag = Boolean::New(isolate, true);
    obj->Set(String::NewFromUtf8(isolate, "boolValue"), flag);

    // Array type
    Local<Array> array = Array::New(isolate);
    array->Set(0, Number::New(isolate, 0));
    array->Set(1, Number::New(isolate, 1));
    array->Set(2, Number::New(isolate, 2));
    array->Set(3, Number::New(isolate, 3));
    obj->Set(String::NewFromUtf8(isolate, "arrayValue"), array);

    // undefined type
    // Local<Value> und = Undefined(isolate);
    // obj->Set(String::NewFromUtf8(isolate, "undefinedValue"), und);

    // Null type
    // Local<Value> null = Null(isolate);
    // obj->Set(String::NewFromUtf8(isolate, "nullValue"), null);

    // Function type
    // Local<FunctionTemplate> ft = FunctionTemplate::New(isolate, MyFunction);
    // Local<Function> fn = ft->GetFunction();
    // fn->SetName(String::NewFromUtf8(isolate, "myFunction"));

    args.GetReturnValue().Set(obj);
}

void init(Local<Object> exports) {
    NODE_SET_METHOD(exports, "getTestValue", TestValue);
}

NODE_MODULE(add, init);

js测试代码:

const addon =  require('./build/Release/addon-test');

console.log("This should be eight:" + JSON.stringify(addon.getTestValue()));

生成结果为:

Hello TestValue
This should be eight:{"numValue":100,"strValue":"Hello world!","boolValue":true,"arrayValue":[0,1,2,3]}


可以看出,c++中的数据也传到了js层,并对应着不同的类型。




  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值