c++嵌入v8参数传递及返回值获取

c++嵌入v8参数传递及获取返回值

参数

嵌入v8函数调用传递参数有2种方式,一种是全局参数放在global context中, 直接可以使用变量名; 另外一种是给函数传递参数属于当前context参数作用域.

全局参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
//组装请求数据context全局变量
static v8::Local<v8::ObjectTemplate> CreateGetLevelCountGlobalObject(v8::Isolate* isolate, const PaymentUserInfo& userInfo) {
v8::Local<v8::ObjectTemplate> global_object = v8::ObjectTemplate::New(isolate);
//用户信息对象 userInfo
v8::Local<v8::ObjectTemplate> global_user_info_object = v8::ObjectTemplate::New(isolate);
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "id").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userInfo.id));
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "userNewId").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.userNewId.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "userOldId").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.userOldId.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "userName").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.userName.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "phone").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.phone.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "cardNo").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.cardNo.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "compnayId").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userInfo.compnayId.c_str()).ToLocalChecked());
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "payCnt").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userInfo.payCnt));
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "fillCnt").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userInfo.fillCnt));
global_user_info_object->Set(v8::String::NewFromUtf8(isolate, "meterId").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userInfo.meterId));

//公共信息对象commonInfo
v8::Local<v8::ObjectTemplate> global_common_info_object = v8::ObjectTemplate::New(isolate);
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "buyTotalQuantity").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.buyTotalQuantity));
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "buyTotalMoney").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.buyTotalMoney));
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "yearTotalQuantity").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.buyTotalMoney));
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "chargePoorId").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.commonField.chargePoorId.c_str()).ToLocalChecked());
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "chargePoorPrice").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.chargePoorPrice));
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "chargePoorMonthMaxMoney").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.chargePoorMonthMaxMoney));
global_common_info_object->Set(v8::String::NewFromUtf8(isolate, "monthTotalMoney").ToLocalChecked(), v8::Integer::New(isolate, userInfo.commonField.monthTotalMoney));


//收费价格对象 priceInfo
v8::Local<v8::ObjectTemplate> global_price_info_object = v8::ObjectTemplate::New(isolate);
global_price_info_object->Set(v8::String::NewFromUtf8(isolate, "id").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userPriceType.id));
global_price_info_object->Set(v8::String::NewFromUtf8(isolate, "detailId").ToLocalChecked(), v8::Integer::New(isolate, userInfo.userPriceType.detailId));
global_price_info_object->Set(v8::String::NewFromUtf8(isolate, "price").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.userPriceType.price.c_str()).ToLocalChecked());

//最后一次缴费记录 lastPayInfo
v8::Local<v8::ObjectTemplate> global_last_pay_info_object = v8::ObjectTemplate::New(isolate);
global_last_pay_info_object->Set(v8::String::NewFromUtf8(isolate, "payMoney").ToLocalChecked(), v8::Integer::New(isolate, userInfo.lastPaymentRecord.payMoney));
global_last_pay_info_object->Set(v8::String::NewFromUtf8(isolate, "surplus").ToLocalChecked(), v8::Number::New(isolate, userInfo.lastPaymentRecord.surplus));
global_last_pay_info_object->Set(v8::String::NewFromUtf8(isolate, "lastSurplus").ToLocalChecked(), v8::Number::New(isolate, userInfo.lastPaymentRecord.lastSurplus));

//ic信息 cardInfo
v8::Local<v8::ObjectTemplate> global_card_info_object = v8::ObjectTemplate::New(isolate);
global_card_info_object->Set(v8::String::NewFromUtf8(isolate, "id").ToLocalChecked(), v8::Integer::New(isolate, userInfo.cardParamInfo.id));
global_card_info_object->Set(v8::String::NewFromUtf8(isolate, "isDelete").ToLocalChecked(), v8::Integer::New(isolate, userInfo.cardParamInfo.isDelete));
global_card_info_object->Set(v8::String::NewFromUtf8(isolate, "name").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.cardParamInfo.name.c_str()).ToLocalChecked());
global_card_info_object->Set(v8::String::NewFromUtf8(isolate, "paramSet").ToLocalChecked(), v8::String::NewFromUtf8(isolate, userInfo.cardParamInfo.paramSet.c_str()).ToLocalChecked());

//填充global对象
global_object->Set(v8::String::NewFromUtf8(isolate, "userInfo").ToLocalChecked(), global_user_info_object);
global_object->Set(v8::String::NewFromUtf8(isolate, "commonInfo").ToLocalChecked(), global_common_info_object);
global_object->Set(v8::String::NewFromUtf8(isolate, "priceInfo").ToLocalChecked(), global_price_info_object);
global_object->Set(v8::String::NewFromUtf8(isolate, "lastPayInfo").ToLocalChecked(), global_last_pay_info_object);
global_object->Set(v8::String::NewFromUtf8(isolate, "cardInfo").ToLocalChecked(), global_card_info_object);
global_object->Set(v8::String::NewFromUtf8(isolate, "log").ToLocalChecked(), v8::FunctionTemplate::New(isolate, LogCallback));
return global_object;
}

函数参数

1
2
//创建js函数调用参数   这里需要传入充值金额、获取用户信息对象
v8::Local<v8::Value> funArg = v8::String::NewFromUtf8(isolate, money).ToLocalChecked();

参数使用

全局参数直接在js中使用变量名即可获取到,函数参数在当前函数中有效,出了函数作用域不可访问.

1
2
3
4
5
6
7
8
9
10
11
12
function testFunction(money) {
var outJsonObject = {};
//直接使用函数参数money 当前context下有效
var MoneyCnt_Pre = parseFloat(money);
//全局参数priceInfo 在global context下有效
var StepPrice = priceInfo.price;

log('input is ' + money);
if (isNaN(MoneyCnt_Pre) || StepPrice == "") {
return JSON.stringify(outJsonObject);
}
}

返回值获取

返回值通过v8::Value接收返回值, 然后转成v8::String::Utf8Value对象,直接使用操作符获取到char数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
v8::TryCatch tryCatch(isolate);
//调用js函数 传递参数并获取返回值
v8::MaybeLocal<v8::Value> funResult =
functionValue.As<v8::Object>()->CallAsFunction(context, context->Global(), 1, &funArg);

if (!funResult.IsEmpty())
{
v8::String::Utf8Value utf8Value(isolate, funResult.ToLocalChecked());
spdlog::info("调用js函数ProcessLevelCount({})获取的返回值{}", money, *utf8Value);
outJson.clear();
outJson.append(*utf8Value);
bResult = true;
}
else {
//调用失败的话 需要从异常里面拿到异常信息
v8::String::Utf8Value utf8Value(isolate, tryCatch.Message()->Get());
spdlog::error("js调用失败,错误信息{}", *utf8Value);
}
}

异常处理

在js中不可避免会产生异常,c++中想要获取到js发生的异常信息,使用v8::TryCatch 声明一个对象,然后进行v8函数调用,发生异常后可以从trycatch对象中获取到js中发生的异常信息.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
v8::TryCatch tryCatch(isolate);
//调用js函数 传递参数并获取返回值
v8::MaybeLocal<v8::Value> funResult =
functionValue.As<v8::Object>()->CallAsFunction(context, context->Global(), 1, &funArg);

if (!funResult.IsEmpty())
{
v8::String::Utf8Value utf8Value(isolate, funResult.ToLocalChecked());
spdlog::info("调用js函数ProcessLevelCount({})获取的返回值{}", money, *utf8Value);
outJson.clear();
outJson.append(*utf8Value);
bResult = true;
}
else {
//调用失败的话 需要从异常里面拿到异常信息
v8::String::Utf8Value utf8Value(isolate, tryCatch.Message()->Get());
spdlog::error("js调用失败,错误信息{}", *utf8Value);
}
}
文章目录
  1. 1. 参数
    1. 1.1. 全局参数
    2. 1.2. 函数参数
    3. 1.3. 参数使用
  2. 2. 返回值获取
  3. 3. 异常处理