1# 使用JSVM-API接口创建和获取string值
2
3## 简介
4
5使用JSVM-API关于string的六个接口,可以让JSVM模块和JavaScript字符串进行交互。
6
7## 基本概念
8
9string是编程中常用的数据类型之一。它可以存储和操作文本数据,用于表示和处理字符序列。还可用于构建用户界面元素,如标签、按钮和文本框,处理用户输入,验证和格式化输入数据。不同的编码支持不同的字符集和语言,以下是一些主要的编码方案及其区别:
10
11- **ASCII**:ASCII是最早的字符编码方案之一,使用7位编码,只能表示英文字母、数字和一些基本符号。它是许多其他编码方案的基础。
12- **UTF-8**:UTF-8是一种变长编码方案,可以表示全球范围的字符集。它使用8位编码,根据字符的不同范围使用不同长度的字节序列。UTF-8是互联网上广泛使用的编码方案。
13- **UTF-16**:UTF-16是一种定长或变长编码方案,使用16位编码。它可以表示全球范围的字符集,并且适用于较大的字符集。
14- **ISO-8859-1(Latin-1)**:ISO-8859-1是一种单字节编码方案,使用8位编码。它主要用于表示拉丁字母字符集,包括欧洲大部分语言。
15
16## 接口说明
17
18| 接口                       | 功能说明                       |
19|----------------------------|--------------------------------|
20| OH_JSVM_GetValueStringUtf8       | 获取给定JavaScript string对象的Utf8编码字符串。|
21| OH_JSVM_CreateStringUtf8          | 根据Utf8编码的字符串创建一个JavaScript string对象。|
22| OH_JSVM_GetValueStringUtf16      | 获取给定JavaScript string对象的Utf16编码字符串|
23| OH_JSVM_CreateStringUtf16         | 根据Utf16编码的字符串数据创建JavaScript string对象。|
24| OH_JSVM_GetValueStringLatin1     | 获取给定JavaScript string对象的Latin1编码字符串|
25| OH_JSVM_CreateStringLatin1        | 根据Latin-1编码的字符串创建一个JavaScript string对象。|
26
27## 使用示例
28
29JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](use-jsvm-process.md),本文仅对接口对应C++相关代码进行展示。
30
31### OH_JSVM_GetValueStringUtf8
32
33OH_JSVM_GetValueStringUtf8接口可以将JavaScript的字符类型的数据转换为utf8编码的字符。
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#include <cstdlib>
43// OH_JSVM_GetValueStringUtf8的样例方法
44static JSVM_Value GetValueStringUtf8(JSVM_Env env, JSVM_CallbackInfo info)
45{
46    size_t argc = 1;
47    JSVM_Value args[1] = {nullptr};
48    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
49    size_t length = 0;
50    JSVM_Status status = OH_JSVM_GetValueStringUtf8(env, args[0], nullptr, 0, &length);
51    char *buf = (char *)malloc(length + 1);
52    status = OH_JSVM_GetValueStringUtf8(env, args[0], buf, length + 1, &length);
53    if (status != JSVM_OK) {
54        OH_LOG_ERROR(LOG_APP, "JSVM GetValueStringUtf8 fail");
55        free(buf);
56        return nullptr;
57    } else {
58        OH_LOG_INFO(LOG_APP, "JSVM GetValueStringUtf8 success: %{public}s", buf);
59    }
60    JSVM_Value result = nullptr;
61    OH_JSVM_CreateStringUtf8(env, buf, length, &result);
62    free(buf);
63    return result;
64}
65// GetValueStringUtf8注册回调
66static JSVM_CallbackStruct param[] = {
67    {.data = nullptr, .callback = GetValueStringUtf8},
68};
69static JSVM_CallbackStruct *method = param;
70// GetValueStringUtf8方法别名,供JS调用
71static JSVM_PropertyDescriptor descriptor[] = {
72    {"getValueStringUtf8", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
73};
74
75// 样例测试js
76const char *srcCallNative = R"JS(
77    let data = "aaBC+-$%^你好123";
78    let script = getValueStringUtf8(data);
79)JS";
80```
81
82预期输出结果
83
84![GetValueStringUtf8](figures/jsvm_about_string_GetValueStringUtf8.png)
85
86**注意事项**:`getValueStringUtf8(arg)`入参`arg`非字符串型数据时接口会调用失败。
87
88### OH_JSVM_CreateStringUtf8
89
90用于创建一个UTF-8编码的JavaScript字符串。
91
92cpp部分代码
93
94```cpp
95// hello.cpp
96#include "napi/native_api.h"
97#include "ark_runtime/jsvm.h"
98#include <hilog/log.h>
99#include <string>
100// OH_JSVM_CreateStringUtf8的样例方法
101static JSVM_Value CreateStringUtf8(JSVM_Env env, JSVM_CallbackInfo info)
102{
103    const char *str = u8"你好, World!, successes to create UTF-8 string!";
104    size_t length = strlen(str);
105    JSVM_Value result = nullptr;
106    JSVM_Status status = OH_JSVM_CreateStringUtf8(env, str, length, &result);
107    if (status != JSVM_OK) {
108        OH_JSVM_ThrowError(env, nullptr, "Failed to create UTF-8 string");
109        return nullptr;
110    } else {
111        OH_LOG_INFO(LOG_APP, "JSVM CreateStringUtf8 success: %{public}s", str);
112    }
113    return result;
114}
115// CreateStringUtf8注册回调
116static JSVM_CallbackStruct param[] = {
117    {.data = nullptr, .callback = CreateStringUtf8},
118};
119static JSVM_CallbackStruct *method = param;
120// CreateStringUtf8方法别名,供JS调用
121static JSVM_PropertyDescriptor descriptor[] = {
122    {"createStringUtf8", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
123};
124
125// 样例测试js
126const char *srcCallNative = R"JS(
127    let script = createStringUtf8();
128)JS";
129```
130
131预期输出结果
132
133![CreateStringUtf8](figures/jsvm_about_string_CreateStringUtf8.png)
134
135### OH_JSVM_GetValueStringUtf16
136
137OH_JSVM_GetValueStringUtf16,将JavaScript的字符类型的数据转换为utf16编码的字符。
138
139cpp部分代码
140
141```cpp
142// hello.cpp
143#include "napi/native_api.h"
144#include "ark_runtime/jsvm.h"
145#include <hilog/log.h>
146#include <codecvt>
147#include <locale>
148#include <cstdlib>
149
150// OH_JSVM_GetValueStringUtf16的样例方法
151// 定义字符串缓冲区的最大长度
152static const int MAX_BUFFER_SIZE = 128;
153static JSVM_Value GetValueStringUtf16(JSVM_Env env, JSVM_CallbackInfo info) {
154    size_t argc = 1;
155    JSVM_Value args[1] = {nullptr};
156    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
157    JSVM_Value result = nullptr;
158    size_t length = 0;
159    char16_t buffer[MAX_BUFFER_SIZE] = {0};
160    // 字符串的缓冲区大小
161    size_t bufferSize = MAX_BUFFER_SIZE;
162    JSVM_Status status = OH_JSVM_GetValueStringUtf16(env, args[0], buffer, bufferSize, &length);
163    // 将 char16_t 转换为 std::u16string
164    std::u16string u16str = {buffer};
165    // 将 std::u16string 转换为 std::string
166    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
167    std::string str = converter.to_bytes(u16str);
168    // 获取字符串返回结果
169    if (status != JSVM_OK) {
170        OH_LOG_ERROR(LOG_APP, "JSVM GetValueStringUtf16 fail");
171        return nullptr;
172    } else {
173        OH_LOG_INFO(LOG_APP, "JSVM GetValueStringUtf16 success: %{public}s", str.c_str());
174    }
175    return result;
176}
177// GetValueStringUtf16注册回调
178static JSVM_CallbackStruct param[] = {
179    {.data = nullptr, .callback = GetValueStringUtf16},
180};
181static JSVM_CallbackStruct *method = param;
182// GetValueStringUtf16方法别名,供JS调用
183static JSVM_PropertyDescriptor descriptor[] = {
184    {"getValueStringUtf16", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
185};
186
187// 样例测试js
188const char *srcCallNative = R"JS(
189    let data = "ahello。";
190    let script = getValueStringUtf16(data);
191)JS";
192```
193
194预期输出结果
195
196![GetValueStringUtf16](figures/jsvm_about_string_GetValueStringUtf16.png)
197
198**注意事项**:`getValueStringUtf16(arg)`入参`arg`非字符串型数据时接口会调用失败。
199
200### OH_JSVM_CreateStringUtf16
201
202用于创建一个UTF-16编码的JavaScript字符串。
203
204cpp部分代码
205
206```cpp
207// hello.cpp
208#include "napi/native_api.h"
209#include "ark_runtime/jsvm.h"
210#include <hilog/log.h>
211#include <codecvt>
212#include <locale>
213#include <cstring>
214
215// OH_JSVM_CreateStringUtf16的样例方法
216static JSVM_Value CreateStringUtf16(JSVM_Env env, JSVM_CallbackInfo info)
217{
218    const char16_t *str = u"你好, World!, successes to create UTF-16 string!";
219    std::u16string ustr(str);
220    size_t length = ustr.length();
221    JSVM_Value result = nullptr;
222    JSVM_Status status = OH_JSVM_CreateStringUtf16(env, str, length, &result);
223    std::u16string u16str = {str};
224    // 将 std::u16string 转换为 std::string
225    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
226    std::string strResult = converter.to_bytes(u16str);
227    if (status != JSVM_OK) {
228        OH_LOG_ERROR(LOG_APP, "JSVM CreateStringUtf16 fail");
229    }else {
230        OH_LOG_INFO(LOG_APP, "JSVM CreateStringUtf16 success: %{public}s", strResult.c_str());
231    }
232    return result;
233}
234// CreateStringUtf16注册回调
235static JSVM_CallbackStruct param[] = {
236    {.data = nullptr, .callback = CreateStringUtf16},
237};
238static JSVM_CallbackStruct *method = param;
239// CreateStringUtf16方法别名,供JS调用
240static JSVM_PropertyDescriptor descriptor[] = {
241    {"createStringUtf16", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
242};
243
244// 样例测试js
245const char *srcCallNative = R"JS(
246    let script = createStringUtf16();
247)JS";
248```
249
250预期输出结果
251
252![CreateStringUtf16](figures/jsvm_about_string_CreateStringUtf16.png)
253
254### OH_JSVM_GetValueStringLatin1
255
256OH_JSVM_GetValueStringLatin1接口可以将JavaScript的字符类型的数据转换为ISO-8859-1编码的字符。
257
258cpp部分代码
259
260```cpp
261// hello.cpp
262#include "napi/native_api.h"
263#include "ark_runtime/jsvm.h"
264#include <hilog/log.h>
265#include <cstdlib>
266// OH_JSVM_GetValueStringLatin1的样例方法
267// 定义字符串缓冲区的最大长度
268static const int MAX_BUFFER_SIZE = 128;
269static JSVM_Value GetValueStringLatin1(JSVM_Env env, JSVM_CallbackInfo info)
270{
271    size_t argc = 1;
272    JSVM_Value args[1] = {nullptr};
273    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
274    char buf[MAX_BUFFER_SIZE];
275    size_t length;
276    JSVM_Value jsvmRes = nullptr;
277    JSVM_Status status = OH_JSVM_GetValueStringLatin1(env, args[0], buf, MAX_BUFFER_SIZE, &length);
278    if (status != JSVM_OK) {
279        OH_LOG_ERROR(LOG_APP, "JSVM GetValueStringLatin1 fail");
280    } else {
281        OH_LOG_INFO(LOG_APP, "JSVM GetValueStringLatin1 success: %{public}s", buf);
282    }
283    OH_JSVM_CreateStringLatin1(env, buf, length, &jsvmRes);
284    return jsvmRes;
285}
286// GetValueStringLatin1注册回调
287static JSVM_CallbackStruct param[] = {
288    {.data = nullptr, .callback = GetValueStringLatin1},
289};
290static JSVM_CallbackStruct *method = param;
291// GetValueStringLatin1方法别名,供JS调用
292static JSVM_PropertyDescriptor descriptor[] = {
293    {"getValueStringLatin1", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
294};
295
296// 样例测试js
297const char *srcCallNative = R"JS(
298    let data = "中文";
299    let script = getValueStringLatin1(data);
300)JS";
301```
302
303预期输出结果
304
305*ISO-8859-1编码不支持中文,传入中文字符会乱码*
306![GetValueStringLatin1](figures/jsvm_about_string_GetValueStringLatin1.png)
307
308**注意事项**:`getValueStringLatin1(arg)`入参`arg`非字符串型数据时接口会调用失败。
309
310### OH_JSVM_CreateStringLatin1
311
312用于创建一个Latin1编码的JavaScript字符串。
313
314cpp部分代码
315
316```cpp
317// hello.cpp
318#include "napi/native_api.h"
319#include "ark_runtime/jsvm.h"
320#include <hilog/log.h>
321#include <cstring>
322// CreateStringLatin1注册回调
323// 定义字符串缓冲区的最大长度
324static const int MAX_BUFFER_SIZE = 128;
325// OH_JSVM_CreateStringLatin1的样例方法
326static JSVM_Value CreateStringLatin1(JSVM_Env env, JSVM_CallbackInfo info)
327{
328    const char *str = "Hello, World! éçñ, successes to create Latin1 string!";
329    size_t length = JSVM_AUTO_LENGTH;
330    JSVM_Value result = nullptr;
331    JSVM_Status status = OH_JSVM_CreateStringLatin1(env, str, length, &result);
332    if (status != JSVM_OK) {
333        OH_LOG_ERROR(LOG_APP, "JSVM CreateStringLatin1 fail");
334    } else {
335        char buf[MAX_BUFFER_SIZE];
336        size_t length;
337        OH_JSVM_GetValueStringLatin1(env, result, buf, MAX_BUFFER_SIZE, &length);
338        OH_LOG_INFO(LOG_APP, "JSVM CreateStringLatin1 success: %{public}s", buf);
339    }
340    return result;
341}
342static JSVM_CallbackStruct param[] = {
343    {.data = nullptr, .callback = CreateStringLatin1},
344};
345static JSVM_CallbackStruct *method = param;
346// CreateStringLatin1方法别名,供JS调用
347static JSVM_PropertyDescriptor descriptor[] = {
348    {"createStringLatin1", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
349};
350
351// 样例测试js
352const char *srcCallNative = R"JS(
353    let script = createStringLatin1();
354)JS";
355```
356
357预期输出结果
358
359![CreateStringLatin1](figures/jsvm_about_string_CreateStringLatin1.png)
360