使用JSVM-API接口创建和获取string值
========================

#### 简介

使用JSVM-API的六个字符串接口，可以实现JSVM模块与JavaScript字符串的交互功能。

#### 基本概念

string是编程中常用的数据类型。用于存储和操作文本数据，它们可用于构建用户界面元素，如标签、按钮和文本框，处理用户输入，验证和格式化数据。不同的编码方案支持不同的字符集和语言，以下是一些主要的编码方案及其区别：

*   **ASCII**：ASCII是最早的字符编码方案之一，使用7位编码，只能表示英文字母、数字和一些基本符号。它是许多其他编码方案的基础。
*   **UTF-8**：UTF-8是一种变长编码方案，可以表示全球范围的字符集。它使用8位编码，根据字符的不同范围使用不同长度的字节序列。UTF-8是互联网上广泛使用的编码方案。
*   **UTF-16**：UTF-16是一种定长或变长编码方案，使用16位编码。它可以表示全球范围的字符集，并且适用于较大的字符集。
*   **ISO-8859-1（Latin-1）**：ISO-8859-1是一种单字节编码方案，使用8位编码。它主要用于表示拉丁字母字符集，包括欧洲大部分语言。

#### 接口说明

| 接口 | 功能说明 |
| :-- | :-- |
| OH\_JSVM\_GetValueStringUtf8 | 获取给定JavaScript string对象的Utf8编码字符串。 |
| OH\_JSVM\_CreateStringUtf8 | 根据Utf8编码的字符串创建一个JavaScript string对象。 |
| OH\_JSVM\_GetValueStringUtf16 | 获取给定JavaScript string对象的Utf16编码字符串。 |
| OH\_JSVM\_CreateStringUtf16 | 根据Utf16编码的字符串数据创建JavaScript string对象。 |
| OH\_JSVM\_GetValueStringLatin1 | 获取给定JavaScript string对象的Latin-1编码字符串。 |
| OH\_JSVM\_CreateStringLatin1 | 根据Latin-1编码的字符串创建一个JavaScript string对象。 |

#### 使用示例

JSVM-API接口开发流程参考[使用JSVM-API实现JS与C/C++语言交互开发流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-jsvm-process)。本文仅展示接口对应的C++相关代码。

#### \[h2\]OH\_JSVM\_GetValueStringUtf8

OH\_JSVM\_GetValueStringUtf8接口可以将JavaScript的字符类型的数据转换为utf8编码的字符。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <cstdlib>
// OH\_JSVM\_GetValueStringUtf8的样例方法
static JSVM\_Value GetValueStringUtf8(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    size\_t length = 0;
    JSVM\_Status status = OH\_JSVM\_GetValueStringUtf8(env, args\[0\], nullptr, 0, &length);
    char \*buf = (char \*)malloc(length + 1);
    if (buf == nullptr) {
        OH\_LOG\_ERROR(LOG\_APP, "malloc failed");
        return nullptr;
    }
    memset(buf, 0, length + 1);
    status = OH\_JSVM\_GetValueStringUtf8(env, args\[0\], buf, length + 1, &length);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetValueStringUtf8 fail");
        free(buf);
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetValueStringUtf8 success: %{public}s", buf);
    }
    JSVM\_Value result = nullptr;
    OH\_JSVM\_CreateStringUtf8(env, buf, length, &result);
    free(buf);
    return result;
}
// GetValueStringUtf8注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetValueStringUtf8},
};
static JSVM\_CallbackStruct \*method = param;
// GetValueStringUtf8方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getValueStringUtf8", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let data = "aaBC+-$%^你好123";
    let script = getValueStringUtf8(data);
)JS";

预期输出结果：

JSVM GetValueStringUtf8 success: aaBC+-$%^你好123

**注意事项**：getValueStringUtf8(arg)入参arg非字符串型数据时接口会调用失败。

#### \[h2\]OH\_JSVM\_CreateStringUtf8

用于创建一个UTF-8编码的JavaScript字符串。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <string>
// OH\_JSVM\_CreateStringUtf8的样例方法
static JSVM\_Value CreateStringUtf8(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    const char \*str = u8"你好, World!, succeed in creating UTF-8 string!";
    size\_t length = strlen(str);
    JSVM\_Value result = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateStringUtf8(env, str, length, &result);
    if (status != JSVM\_OK) {
        OH\_JSVM\_ThrowError(env, nullptr, "Failed to create UTF-8 string");
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateStringUtf8 success: %{public}s", str);
    }
    return result;
}
// CreateStringUtf8注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateStringUtf8},
};
static JSVM\_CallbackStruct \*method = param;
// CreateStringUtf8方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createStringUtf8", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let script = createStringUtf8();
)JS";

预期输出结果：

JSVM CreateStringUtf8 success: 你好, World!, succeed in creating UTF-8 string!

#### \[h2\]OH\_JSVM\_GetValueStringUtf16

OH\_JSVM\_GetValueStringUtf16，将JavaScript的字符类型的数据转换为utf16编码的字符。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <codecvt>
#include <locale>
#include <cstdlib>

// OH\_JSVM\_GetValueStringUtf16的样例方法
// 定义字符串缓冲区的最大长度
static const int MAX\_BUFFER\_SIZE = 128;
static JSVM\_Value GetValueStringUtf16(JSVM\_Env env, JSVM\_CallbackInfo info) {
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    JSVM\_Value result = nullptr;
    size\_t length = 0;
    char16\_t buffer\[MAX\_BUFFER\_SIZE\] = {0};
    // 字符串的缓冲区大小
    size\_t bufferSize = MAX\_BUFFER\_SIZE;
    JSVM\_Status status = OH\_JSVM\_GetValueStringUtf16(env, args\[0\], buffer, bufferSize, &length);
    // 将 char16\_t 转换为 std::u16string
    std::u16string u16str = {buffer};
    // 将 std::u16string 转换为 std::string
    std::wstring\_convert<std::codecvt\_utf8\_utf16<char16\_t>, char16\_t> converter;
    std::string str = converter.to\_bytes(u16str);
    // 获取字符串返回结果
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetValueStringUtf16 fail");
        return nullptr;
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetValueStringUtf16 success: %{public}s", str.c\_str());
    }
    return result;
}
// GetValueStringUtf16注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetValueStringUtf16},
};
static JSVM\_CallbackStruct \*method = param;
// GetValueStringUtf16方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getValueStringUtf16", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let data = "ahello。";
    let script = getValueStringUtf16(data);
)JS";

预期输出结果：

JSVM GetValueStringUtf16 success: ahello。

**注意事项**：getValueStringUtf16(arg)的参数arg必须是字符串，否则接口会调用失败。

#### \[h2\]OH\_JSVM\_CreateStringUtf16

用于创建一个UTF-16编码的JavaScript字符串。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <codecvt>
#include <locale>
#include <cstring>

// OH\_JSVM\_CreateStringUtf16的样例方法
static JSVM\_Value CreateStringUtf16(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    const char16\_t \*str = u"你好, World!, succeed in creating UTF-16 string!";
    std::u16string ustr(str);
    size\_t length = ustr.length();
    JSVM\_Value result = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateStringUtf16(env, str, length, &result);
    std::u16string u16str = {str};
    // 将 std::u16string 转换为 std::string
    std::wstring\_convert<std::codecvt\_utf8\_utf16<char16\_t>, char16\_t> converter;
    std::string strResult = converter.to\_bytes(u16str);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateStringUtf16 fail");
    }else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateStringUtf16 success: %{public}s", strResult.c\_str());
    }
    return result;
}
// CreateStringUtf16注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateStringUtf16},
};
static JSVM\_CallbackStruct \*method = param;
// CreateStringUtf16方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createStringUtf16", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let script = createStringUtf16();
)JS";

预期输出结果：

JSVM CreateStringUtf16 success: 你好, World!, succeed in creating UTF-16 string!

#### \[h2\]OH\_JSVM\_GetValueStringLatin1

OH\_JSVM\_GetValueStringLatin1接口可以将JavaScript的字符类型的数据转换为ISO-8859-1编码的字符。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <cstdlib>
// OH\_JSVM\_GetValueStringLatin1的样例方法
// 定义字符串缓冲区的最大长度
static const int MAX\_BUFFER\_SIZE = 128;
static JSVM\_Value GetValueStringLatin1(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    size\_t argc = 1;
    JSVM\_Value args\[1\] = {nullptr};
    OH\_JSVM\_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
    char buf\[MAX\_BUFFER\_SIZE\];
    size\_t length = 0;
    JSVM\_Value jsvmRes = nullptr;
    JSVM\_Status status = OH\_JSVM\_GetValueStringLatin1(env, args\[0\], buf, MAX\_BUFFER\_SIZE, &length);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM GetValueStringLatin1 fail");
    } else {
        OH\_LOG\_INFO(LOG\_APP, "JSVM GetValueStringLatin1 success: %{public}s", buf);
    }
    OH\_JSVM\_CreateStringLatin1(env, buf, length, &jsvmRes);
    return jsvmRes;
}
// GetValueStringLatin1注册回调
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = GetValueStringLatin1},
};
static JSVM\_CallbackStruct \*method = param;
// GetValueStringLatin1方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"getValueStringLatin1", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let data = "中文";
    let script = getValueStringLatin1(data);
)JS";

预期输出结果（ISO-8859-1编码不支持中文，传入中文字符会导致乱码）：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/75/v3/hygMoVrDQKqtUh3mizR-xg/zh-cn_image_0000002633850236.png?HW-CC-KV=V1&HW-CC-Date=20260709T132820Z&HW-CC-Expire=86400&HW-CC-Sign=4D89E81EF15F5B860C519DEAEEED05B7F11241D0885F1234EAA53E60B64C1A2B)

**注意事项**：getValueStringLatin1(arg)入参arg必须为字符串类型，否则接口调用会失败。

#### \[h2\]OH\_JSVM\_CreateStringLatin1

用于创建一个Latin1编码的JavaScript字符串。

cpp部分代码：

// hello.cpp
#include "napi/native\_api.h"
#include "ark\_runtime/jsvm.h"
#include <hilog/log.h>
#include <cstring>
// CreateStringLatin1注册回调
// 定义字符串缓冲区的最大长度
static const int MAX\_BUFFER\_SIZE = 128;
// OH\_JSVM\_CreateStringLatin1的样例方法
static JSVM\_Value CreateStringLatin1(JSVM\_Env env, JSVM\_CallbackInfo info)
{
    const char \*str = "Hello, World! éçñ, succeed in creating Latin1 string!";
    size\_t length = JSVM\_AUTO\_LENGTH;
    JSVM\_Value result = nullptr;
    JSVM\_Status status = OH\_JSVM\_CreateStringLatin1(env, str, length, &result);
    if (status != JSVM\_OK) {
        OH\_LOG\_ERROR(LOG\_APP, "JSVM CreateStringLatin1 fail");
    } else {
        char buf\[MAX\_BUFFER\_SIZE\];
        size\_t length = 0;
        OH\_JSVM\_GetValueStringLatin1(env, result, buf, MAX\_BUFFER\_SIZE, &length);
        OH\_LOG\_INFO(LOG\_APP, "JSVM CreateStringLatin1 success: %{public}s", buf);
    }
    return result;
}
static JSVM\_CallbackStruct param\[\] = {
    {.data = nullptr, .callback = CreateStringLatin1},
};
static JSVM\_CallbackStruct \*method = param;
// CreateStringLatin1方法别名，供JS调用
static JSVM\_PropertyDescriptor descriptor\[\] = {
    {"createStringLatin1", nullptr, method++, nullptr, nullptr, nullptr, JSVM\_DEFAULT},
};

// 样例测试js
const char \*srcCallNative = R"JS(
    let script = createStringLatin1();
)JS";

预期输出结果：

JSVM CreateStringLatin1 success: Hello, World! éçñ, succeed in creating Latin1 string!