gpt4 book ai didi

c++ - 从具有非 ASCII 字符的 wchar_t 创建 v8::String 的安全方法是什么?

转载 作者:行者123 更新时间:2023-11-30 02:37:02 25 4
gpt4 key购买 nike

我正在为 DAB development board 编写一个 Node.js 前端,最终将在 Raspberry Pi 上运行。我是一名 Java 和 Web 开发人员,我正在努力使用 C++ 并在不同类型的字符串之间进行转换。

DAB 板带有一个 C++ SDK,具有许多方便的功能。它允许我使用 GetTotalProgram() 获取可用程序的数量。对于每个程序,我都可以调用 GetProgramName 来获取程序的名称:

GetProgramName(char mode, long dabIndex, char namemode, wchar_t * programName)

... 其中mode表示FMDABnamemode表示长名或短名。程序的名称将在 programName 中返回。

为了将 wchar_t *programName 转换为 v8::String,我找到了我正在使用的这个片段,并了解了以下基础知识:

  wchar_t buff[300];
char cbuff[600];
GetProgramName(0, i, 1, buff);
wcstombs( cbuff, buff, wcslen(buff) );
Local<String> str = String::NewFromUtf8(isolate, (const char *) cbuff, v8::String::kNormalString, wcslen(buff));

我遍历可用程序并构建一个 v8::Array:

void GetPrograms(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);

wchar_t buff[300];
char cbuff[600];
int numberOfPrograms, i;

numberOfPrograms = GetTotalProgram();
Local<v8::Array> ARRAY = Array::New(isolate, totalprogram);

for (i = 0; i < numberOfPrograms; i++) {
if (GetProgramName(0, i, 1, buff)) {
wcstombs( cbuff, buff, wcslen(buff) );
Local<String> str = String::NewFromUtf8(isolate, (const char *) cbuff, v8::String::kNormalString, wcslen(buff));
Local<Object> obj = Object::New(isolate);
obj->Set(String::NewFromUtf8(isolate, "name"), str);
ARRAY->Set(i, obj);
}
}
args.GetReturnValue().Set(ARRAY);
}

我从我的 Node 应用程序调用 C++ 方法:

var programs = ext.getPrograms();
for (var i = 0; i < programs.length; i++) {
console.log(programs[i][name]);
}

这主要有效,但当程序名称包含非 ASCII 字符时,例如 ÆØÅ, ARRAY 中的 next 元素有一个乏味的名字

与预期输出相比,这里是 Node 片段实际输出的内容 (console.log):

| ACTUAL    | EXPECTED   |
| --------- | ---------- |
| NRK SUPER | NRK SUPER |
| NRK VUPER | NRK VÆR |
| NRK P1 ER | NRK P1 |

似乎非 ASCII 字符导致下一个 wcstombs 提前退出,而不是复制后面的字符。

为什么会这样?有没有更好的方法从我的 wchar_t 创建一个 v8::String

注意:在 Raspberry Pi 上运行时,我现在已经能够将此问题隔离到 wcstombs 方法。以下代码:

#include <stdio.h>
#include <string>
#include <cstring>
#include <cstdlib>

char cbuff[600];
wchar_t buff[300] = L"ABCø123abc";

int main( int argc, const char* argv[] ) {
wcstombs( cbuff, buff, wcslen(buff) );
wprintf(L"wcslen of wchar_t array: %u - strlen of char array: %u\n", (char) wcslen(buff), strlen(cbuff));
}

在 Mac 上运行时,输出
wchar_t 数组的 wcslen:10 - char 数组的 strlen:10
但是当在 Raspberry 上运行时,输出
wchar_t 数组的 wcslen:10 - char 数组的 strlen:3 - 也就是说,它只计算 ø 字符之前的字符

这看起来类似于 this unanswered question .

最佳答案

WCHAR str[256];0
... // fill str array here
Local<String> v8str = String::NewFromTwoByte(isolate, (const uint16_t *) str);

注意 ::NewFromTwoByte 用法,而不是 ::NewFromUtf8(const uint16_t *) 转换。

::NewFromTwoByte Allocates a new string from UTF-16 data.

关于c++ - 从具有非 ASCII 字符的 wchar_t 创建 v8::String 的安全方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32071478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com