• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用 JSVM-API 提供的proxy接口
2<!--Kit: NDK Development-->
3<!--Subsystem: arkcompiler-->
4<!--Owner: @yuanxiaogou; @string_sz-->
5<!--Designer: @knightaoko-->
6<!--Tester: @test_lzz-->
7<!--Adviser: @fang-jinxu-->
8## 简介
9JSVM-API 提供了创建 Proxy、判断 JSVM_Value 是否为 Proxy 类型和获取 Proxy 中的目标对象的接口。
10
11## 接口说明
12
13| 接口                     | 功能说明                                            |
14| ---------------------- | ----------------------------------------------- |
15| OH_JSVM_CreateProxy    | 创建 Proxy,等价于在 js 中执行 new Proxy(target, handler) |
16| OH_JSVM_IsProxy        | 判断传入的 JSVM_Value 是否为 Proxy 类型                   |
17| OH_JSVM_ProxyGetTarget | 获取给定 proxy 的目标对象                                |
18
19## 使用示例
20JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅展示接口对应的C++相关代码。
21
22cpp 部分代码
23```
24// OH_JSVM_CreateProxy 的样例方法
25static JSVM_Value CreateProxy(JSVM_Env env, JSVM_CallbackInfo info) {
26    // 接受两个入参,第 1 个参数为 target,第 2 个参数为 handler
27    size_t argc = 2;
28    JSVM_Value args[2] = {nullptr};
29    JSVM_CALL(OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr));
30    // 用 OH_JSVM_CreateProxy 为目标对象创建代理
31    JSVM_Value result = nullptr;
32    JSVM_Status status = OH_JSVM_CreateProxy(env, args[0], args[1], &result);
33    if (status != JSVM_OK) {
34        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateProxy: failed: %{public}d", status);
35    } else {
36        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateProxy: success");
37    }
38
39    return result;
40}
41
42// OH_JSVM_IsProxy 的样例方法
43static JSVM_Value IsProxy(JSVM_Env env, JSVM_CallbackInfo info) {
44    size_t argc = 1;
45    JSVM_Value args[1] = {nullptr};
46    JSVM_CALL(OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr));
47    // 调用 OH_JSVM_IsProxy 判断 JSVM_Value 是否为代理
48    bool result = false;
49    JSVM_Status status = OH_JSVM_IsProxy(env, args[0], &result);
50    if (status != JSVM_OK) {
51        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_IsProxy: failed");
52    } else {
53        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_IsProxy: success: %{public}s", result ? "is a proxy" : "is not a proxy");
54    }
55    JSVM_Value isProxy;
56    JSVM_CALL(OH_JSVM_GetBoolean(env, result, &isProxy));
57    return isProxy;
58}
59
60// OH_JSVM_ProxyGetTarget 的样例方法
61static JSVM_Value GetProxyTarget(JSVM_Env env, JSVM_CallbackInfo info) {
62    size_t argc = 1;
63    JSVM_Value args[1] = {nullptr};
64    JSVM_CALL(OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr));
65    // 调用 OH_JSVM_ProxyGetTarget 获取代理中的目标对象
66    JSVM_Value result = nullptr;
67    JSVM_Status status = OH_JSVM_ProxyGetTarget(env, args[0], &result);
68    if (status != JSVM_OK) {
69        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_ProxyGetTarget: failed");
70    } else {
71        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_ProxyGetTarget: success");
72    }
73
74    return result;
75}
76
77// Proxy 相关回调注册
78static JSVM_CallbackStruct param[] = {{.data = nullptr, .callback = CreateProxy},
79                                      {.data = nullptr, .callback = IsProxy},
80                                      {.data = nullptr, .callback = GetProxyTarget}};
81static JSVM_CallbackStruct *method = param;
82// Proxy 相关回调别名
83static JSVM_PropertyDescriptor descriptor[] = {
84    {"CreateProxy", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
85    {"IsProxy", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
86    {"GetProxyTarget", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}};
87
88const char *srcCallNative = R"JS(
89       target = {
90         message1: "hello",
91         message2: "everyone",
92       };
93
94       handler = {
95         get(target, prop, receiver) {
96           return "world";
97         },
98       };
99
100       proxy = CreateProxy(target, handler)
101       isProxy = IsProxy(proxy)
102       target1 = GetProxyTarget(proxy)
103)JS";
104```
105
106预期的输出结果
107```
108JSVM OH_JSVM_CreateProxy: success
109JSVM OH_JSVM_IsProxy: success: is a proxy
110JSVM OH_JSVM_ProxyGetTarget: success
111```