1# 使用JSVM-API接口进行primitive类相关开发
2
3## 简介
4
5在使用JSVM-API接口时,开发人员可以实现在JSVM模块中与JavaScript对象的交互,并进行数据转换和获取特定对象的操作,它们在不同的场景中发挥着重要的作用,使开发人员能够更灵活地处理JavaScript值和对象。
6
7## 基本概念
8
9在使用JSVM操作JavaScript对象时,有一些基本概念需要了解:
10
11- **JavaScript值到C/C++类型的转换:** 在JSVM模块中,可以使用JSVM函数将JavaScript值转换为C/C++的数据类型,如将JavaScript数值转换为C/C++的整数、将JavaScript字符串转换为C/C++的字符数组等。同样,也可以将C/C++的数据类型转换为JavaScript值,以便将结果返回给JavaScript代码。
12
13## 接口说明
14
15| 接口                   | 功能说明                                                |
16| ---------------------- | ------------------------------------------------------- |
17| OH_JSVM_CoerceToBool   | 将目标值转换为Boolean类型对象。   |
18| OH_JSVM_CoerceToNumber | 将目标值转换为Number类型对象。    |
19| OH_JSVM_CoerceToObject | 将目标值转换为Object类型对象。    |
20| OH_JSVM_CoerceToString | 将目标值转换为String类型对象。    |
21| OH_JSVM_GetBoolean       | 获取JavaScript单例对象。 |
22| OH_JSVM_GetValueBool    | 获取给定JavaScript Boolean的C布尔基础类型值。 |
23| OH_JSVM_GetGlobal      | 获取当前环境中的全局global对象。                                      |
24| OH_JSVM_GetNull          | 获取JavaScript null。                                        |
25| OH_JSVM_GetUndefined     | 获取JavaScript undefined。                                   |
26
27## 使用示例
28
29JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
30
31### OH_JSVM_CoerceToBool
32
33用于将一个给定的JavaScript值强制转为JavaScript boolean值。
34
35cpp 部分代码
36
37```cpp
38// hello.cpp
39#include "napi/native_api.h"
40#include "ark_runtime/jsvm.h"
41#include <hilog/log.h>
42// CoerceToBool注册回调
43static JSVM_CallbackStruct param[] = {
44    {.data = nullptr, .callback = CoerceToBool},
45};
46static JSVM_CallbackStruct *method = param;
47// CoerceToBool方法别名,ArkTS侧调用
48static JSVM_PropertyDescriptor descriptor[] = {
49    {"coerceToBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
50};
51// OH_JSVM_CoerceToBool的样例方法
52static JSVM_Value CoerceToBool(JSVM_Env env, JSVM_CallbackInfo info)
53{
54    size_t argc = 1;
55    JSVM_Value args[1] = {nullptr};
56    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
57    JSVM_Value boolean = nullptr;
58    JSVM_Status status = OH_JSVM_CoerceToBool(env, args[0], &boolean);
59    if (status != JSVM_OK) {
60        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToBool failed");
61    } else {
62        bool result = false;
63        OH_JSVM_GetValueBool(env, boolean, &result);
64        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToBool success:%{public}d", result);
65    }
66    return boolean;
67}
68```
69
70ArkTS 侧示例代码
71
72```ts
73import hilog from "@ohos.hilog"
74// 通过import的方式,引入Native能力。
75import napitest from "libentry.so"
76let script: string = `coerceToBool("123")`;
77try {
78  let result = napitest.runJsVm(script);
79  hilog.info(0x0000, 'JSVM', 'CoerceToBool: %{public}s', result);
80} catch (error) {
81  hilog.error(0x0000, 'JSVM', 'CoerceToBool: %{public}s', error.message);
82}
83```
84
85### OH_JSVM_CoerceToNumber
86
87用于将给定的JavaScript value强转为JavaScript number。
88
89cpp 部分代码
90
91```cpp
92// hello.cpp
93#include "napi/native_api.h"
94#include "ark_runtime/jsvm.h"
95#include <hilog/log.h>
96// CoerceToNumber注册回调
97static JSVM_CallbackStruct param[] = {
98    {.data = nullptr, .callback = CoerceToNumber},
99};
100static JSVM_CallbackStruct *method = param;
101// CoerceToNumber方法别名,ArkTS侧调用
102static JSVM_PropertyDescriptor descriptor[] = {
103    {"coerceToNumber", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
104};
105// OH_JSVM_CoerceToNumber的样例方法
106static JSVM_Value CoerceToNumber(JSVM_Env env, JSVM_CallbackInfo info)
107{
108    size_t argc = 1;
109    JSVM_Value args[1] = {nullptr};
110    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
111    JSVM_Value number = nullptr;
112    JSVM_Status status = OH_JSVM_CoerceToNumber(env, args[0], &number);
113    if (status != JSVM_OK) {
114        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToNumber failed");
115    } else {
116        int32_t result = 0;
117        OH_JSVM_GetValueInt32(env, number, &result);
118        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result);
119    }
120    return number;
121}
122```
123
124ArkTS 侧示例代码
125
126```ts
127import hilog from "@ohos.hilog"
128// 通过import的方式,引入Native能力。
129import napitest from "libentry.so"
130let script: string = `coerceToNumber(true)`;
131try {
132  let result = napitest.runJsVm(script);
133  hilog.info(0x0000, 'JSVM', 'CoerceToNumber: %{public}s', result);
134} catch (error) {
135  hilog.error(0x0000, 'JSVM', 'CoerceToNumber: %{public}s', error.message);
136}
137```
138
139### OH_JSVM_CoerceToObject
140
141用于将给定的JavaScript value强转为JavaScript Object类型。
142
143cpp 部分代码:
144
145```cpp
146// hello.cpp
147#include "napi/native_api.h"
148#include "ark_runtime/jsvm.h"
149#include <hilog/log.h>
150// CoerceToObjec注册回调
151static JSVM_CallbackStruct param[] = {
152    {.data = nullptr, .callback = CoerceToObject},
153};
154static JSVM_CallbackStruct *method = param;
155// CoerceToObject方法别名,ArkTS侧调用
156static JSVM_PropertyDescriptor descriptor[] = {
157    {"coerceToObject", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
158};
159// OH_JSVM_CoerceToObject的样例方法
160static JSVM_Value CoerceToObject(JSVM_Env env, JSVM_CallbackInfo info)
161{
162    size_t argc = 1;
163    JSVM_Value args[1] = {nullptr};
164    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
165    JSVM_Value obj = nullptr;
166    JSVM_Status status = OH_JSVM_CoerceToObject(env, args[0], &obj);
167    if (status != JSVM_OK) {
168        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToObject failed");
169        return nullptr;
170    } else {
171        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToObject success");
172    }
173    return obj;
174}
175```
176
177ArkTS侧示例代码
178
179```ts
180import hilog from "@ohos.hilog"
181// 通过import的方式,引入Native能力。
182import napitest from "libentry.so"
183let script: string = `coerceToObject(123)`;
184try {
185  let result = napitest.runJsVm(script);
186  hilog.info(0x0000, 'JSVM', 'CoerceToObject001: %{public}s', result);
187} catch (error) {
188  hilog.error(0x0000, 'JSVM', 'CoerceToObject001: %{public}s', error.message);
189}
190```
191
192### OH_JSVM_CoerceToString
193
194用于将给定的JavaScript value强转为JavaScript string类型。
195
196cpp部分代码
197
198```cpp
199// hello.cpp
200#include "napi/native_api.h"
201#include "ark_runtime/jsvm.h"
202#include <hilog/log.h>
203// CoerceToString注册回调
204static JSVM_CallbackStruct param[] = {
205    {.data = nullptr, .callback = CoerceToString},
206};
207static JSVM_CallbackStruct *method = param;
208// CoerceToString方法别名,ArkTS侧调用
209static JSVM_PropertyDescriptor descriptor[] = {
210    {"coerceToString", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
211};
212// OH_JSVM_CoerceToString的样例方法
213static JSVM_Value CoerceToString(JSVM_Env env, JSVM_CallbackInfo info)
214{
215    size_t argc = 1;
216    JSVM_Value args[1] = {nullptr};
217    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
218    JSVM_Value str = nullptr;
219    JSVM_Status status = OH_JSVM_CoerceToString(env, args[0], &str);
220    if (status != JSVM_OK) {
221        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToString fail");
222        return nullptr;
223    } else {
224        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToString success");
225    }
226    return str;
227}
228```
229
230ArkTS侧示例代码
231
232```ts
233import hilog from "@ohos.hilog"
234// 通过import的方式,引入Native能力。
235import napitest from "libentry.so"
236let script: string = `coerceToString(22222)`;
237try {
238  let result = napitest.runJsVm(script);
239  hilog.info(0x0000, 'JSVM', 'CoerceToString: %{public}s', result);
240} catch (error) {
241  hilog.error(0x0000, 'JSVM', 'CoerceToString: %{public}s', error.message);
242}
243```
244
245### OH_JSVM_GetBoolean
246
247获取给定布尔值的JavaScript单例对象。
248
249cpp部分代码
250
251```cpp
252// hello.cpp
253#include "napi/native_api.h"
254#include "ark_runtime/jsvm.h"
255#include <hilog/log.h>
256// GetBoolean注册回调
257static JSVM_CallbackStruct param[] = {
258    {.data = nullptr, .callback = GetBoolean},
259};
260static JSVM_CallbackStruct *method = param;
261// GetBoolean方法别名,供JS调用
262static JSVM_PropertyDescriptor descriptor[] = {
263    {"getBoolean", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
264};
265// OH_JSVM_GetBoolean的样例方法
266static JSVM_Value GetBoolean(JSVM_Env env, JSVM_CallbackInfo info)
267{
268    // 传入两个参数并解析
269    size_t argc = 2;
270    JSVM_Value argv[2] = {nullptr};
271    OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr);
272    int32_t paramData = 0;
273    OH_JSVM_GetValueInt32(env, argv[0], &paramData);
274    int32_t paramValue = 0;
275    OH_JSVM_GetValueInt32(env, argv[1], &paramValue);
276    JSVM_Value returnValue = nullptr;
277    bool type = false;
278    if (paramData == paramValue) {
279        OH_LOG_INFO(LOG_APP, "JSVM resultType equal");
280        type = true;
281    }
282    JSVM_Status status = OH_JSVM_GetBoolean(env, type, &returnValue);
283    if (status != JSVM_OK) {
284        OH_JSVM_ThrowError(env, nullptr, "JSVM OH_JSVM_CoerceToNumber fail");
285    } else {
286        bool result = false;
287        OH_JSVM_GetValueBool(env, returnValue, &result);
288        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result);
289    }
290    // 返回结果
291    return returnValue;
292}
293```
294
295ArkTS 侧示例代码
296
297```ts
298import hilog from "@ohos.hilog"
299// 通过import的方式,引入Native能力。
300import napitest from "libentry.so"
301try {
302  let data = 1;
303  let compareData = 2;
304  let script: string = `getBoolean(${data}, ${compareData})`;
305  let result = napitest.runJsVm(script);
306  hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result);
307} catch (error) {
308  hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message);
309}
310try {
311  let data = 1;
312  let compareData = 1;
313  let script: string = `getBoolean(${data}, ${compareData})`;
314  let result = napitest.runJsVm(script);
315  hilog.info(0x0000, 'JSVM', 'GetBoolean: %{public}s', result);
316} catch (error) {
317  hilog.error(0x0000, 'JSVM', 'GetBoolean: %{public}s', error.message);
318}
319```
320
321### OH_JSVM_GetValueBool
322
323使用这个函数将JavaScript中的布尔值转为等价的C布尔值。
324
325cpp 部分代码
326
327```cpp
328// hello.cpp
329#include "napi/native_api.h"
330#include "ark_runtime/jsvm.h"
331#include <hilog/log.h>
332// GetValueBool注册回调
333static JSVM_CallbackStruct param[] = {
334    {.data = nullptr, .callback = GetValueBool},
335};
336static JSVM_CallbackStruct *method = param;
337// GetValueBool方法别名,供JS调用
338static JSVM_PropertyDescriptor descriptor[] = {
339    {"getValueBool", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
340};
341// OH_JSVM_GetValueBool的样例方法
342static JSVM_Value GetValueBool(JSVM_Env env, JSVM_CallbackInfo info)
343{
344    size_t argc = 1;
345    JSVM_Value args[1] = {nullptr};
346    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
347    bool result = false;
348    JSVM_Status status = OH_JSVM_GetValueBool(env, args[0], &result);
349    if (status == JSVM_BOOLEAN_EXPECTED || status != JSVM_OK) {
350        // 如果OH_JSVM_GetValueBool成功会返回JSVM_OK,如果传入一个非布尔值则会返回JSVM_BOOLEAN_EXPECTED
351        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetValueBool fail:%{public}d", status);
352        return nullptr;
353    } else {
354        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetValueBool success:%{public}d", result);
355    }
356    JSVM_Value boolJv = nullptr;
357    OH_JSVM_GetBoolean(env, result, &boolJv);
358    return boolJv;
359}
360```
361
362ArkTS 侧示例代码
363
364```ts
365import hilog from "@ohos.hilog"
366// 通过import的方式,引入Native能力。
367import napitest from "libentry.so"
368// 分别传入布尔值和非布尔值检测接口,传入布尔值将返回原布尔值,传入其他类型返回undefined
369try {
370  let data = `"abc"`;
371  let script: string = `getValueBool(${data})`;
372  let result = napitest.runJsVm(script);
373  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
374} catch (error) {
375  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
376}
377try {
378  let data = true;
379  let script: string = `getValueBool(${data})`;
380  let result = napitest.runJsVm(script);
381  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
382} catch (error) {
383  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
384}
385try {
386  let data = false;
387  let script: string = `getValueBool(${data})`;
388  let result = napitest.runJsVm(script);
389  hilog.info(0x0000, 'JSVM', 'GetValueBool: %{public}s', result);
390} catch (error) {
391  hilog.error(0x0000, 'JSVM', 'GetValueBool: %{public}s', error.message);
392}
393```
394
395### OH_JSVM_GetGlobal
396
397用于获取全局JavaScript对象。该函数的主要作用是获取表示JavaScript全局对象的JSVM_Value,使得JSVM模块能够与JavaScript运行时的全局对象进行交互。
398
399cpp 部分代码
400
401```cpp
402// hello.cpp
403#include "napi/native_api.h"
404#include "ark_runtime/jsvm.h"
405#include <hilog/log.h>
406// GetGlobal注册回调
407static JSVM_CallbackStruct param[] = {
408    {.data = nullptr, .callback = GetGlobal},
409};
410static JSVM_CallbackStruct *method = param;
411// GetGlobal方法别名,供JS调用
412static JSVM_PropertyDescriptor descriptor[] = {
413    {"getGlobal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
414};
415// OH_JSVM_GetGlobal的样例方法
416static JSVM_Value GetGlobal(JSVM_Env env, JSVM_CallbackInfo info)
417{
418    // 获取全局对象
419    JSVM_Value value = nullptr;
420    JSVM_Value global = nullptr;
421    OH_JSVM_CreateInt32(env, 1, &value);
422    JSVM_Status status = OH_JSVM_GetGlobal(env, &global);
423    OH_JSVM_SetNamedProperty(env, global, "Row", value);
424    if (status != JSVM_OK) {
425        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetGlobal fail");
426    } else {
427        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetGlobal success");
428    }
429    return global;
430}
431```
432
433ArkTS 侧示例代码
434
435```ts
436import hilog from "@ohos.hilog"
437// 通过import的方式,引入Native能力。
438import napitest from "libentry.so"
439let script: string = `getGlobal()`
440try {
441  let result = napitest.runJsVm(script);
442  hilog.info(0x0000, 'JSVM', 'GetGlobal: %{public}s', result);
443} catch (error) {
444  hilog.error(0x0000, 'JSVM', 'GetGlobal: %{public}s', error.message);
445}
446```
447
448### OH_JSVM_GetNull
449
450用于获取JavaScript null
451
452cpp 部分代码
453
454```cpp
455// hello.cpp
456#include "napi/native_api.h"
457#include "ark_runtime/jsvm.h"
458#include <hilog/log.h>
459// GetNull注册回调
460static JSVM_CallbackStruct param[] = {
461    {.data = nullptr, .callback = GetNull},
462};
463static JSVM_CallbackStruct *method = param;
464// GetNull方法别名,供JS调用
465static JSVM_PropertyDescriptor descriptor[] = {
466    {"getNull", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
467};
468// OH_JSVM_GetNull的样例方法
469static JSVM_Value GetNull(JSVM_Env env, JSVM_CallbackInfo info) {
470    JSVM_Value nullValue = nullptr;
471    JSVM_Status status = OH_JSVM_GetNull(env, &nullValue);
472    if (status != JSVM_OK) {
473        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetNull fail");
474    } else {
475        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNull success");
476    }
477    return nullValue;
478}
479```
480
481ArkTS 侧示例代码
482
483```ts
484import hilog from "@ohos.hilog"
485// 通过import的方式,引入Native能力。
486import napitest from "libentry.so"
487try {
488  let script: string = `getNull()`;
489  let result = napitest.runJsVm(script);
490  hilog.info(0x0000, 'JSVM', 'GetNull: %{public}s', result);
491} catch (error) {
492  hilog.error(0x0000, 'JSVM', 'GetNull: %{public}s', error.message);
493}
494```
495
496### OH_JSVM_GetUndefined
497
498用于获取JavaScript undefined
499
500cpp 部分代码
501
502```cpp
503// hello.cpp
504#include "napi/native_api.h"
505#include "ark_runtime/jsvm.h"
506#include <hilog/log.h>
507// GetUndefined注册回调
508static JSVM_CallbackStruct param[] = {
509    {.data = nullptr, .callback = GetUndefined},
510};
511static JSVM_CallbackStruct *method = param;
512// GetUndefined方法别名,供JS调用
513static JSVM_PropertyDescriptor descriptor[] = {
514    {"getUndefined", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
515};
516// OH_JSVM_GetUndefined的样例方法
517static JSVM_Value GetUndefined(JSVM_Env env, JSVM_CallbackInfo info)
518{
519    // 获取并解析传进的参数
520    size_t argc = 1;
521    JSVM_Value args[1] = {nullptr};
522    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
523    // 创建一个undefined值
524    JSVM_Value value = nullptr;
525    JSVM_Status status = OH_JSVM_GetUndefined(env, &value);
526    if (status != JSVM_OK) {
527        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetUndefined failed");
528    } else {
529        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetUndefined success");
530    }
531    return value;
532}
533```
534
535接口声明
536
537ArkTS 侧示例代码
538
539```ts
540import hilog from "@ohos.hilog"
541// 通过import的方式,引入Native能力。
542import napitest from "libentry.so"
543try {
544  let script: string = `getUndefined()`;
545  let result = napitest.runJsVm(script);
546  hilog.info(0x0000, 'JSVM', 'GetUndefined: %{public}s', result);
547} catch (error) {
548  hilog.error(0x0000, 'JSVM', 'GetUndefined: %{public}s', error.message);
549}
550```
551