【HarmonyOS NEXT】NAPI读取js字符串对象赋值给c++对象会出现乱码或者为空

【关键字】

赋值c++对象 / 乱码

【问题描述】

1、NAPI读取js字符串对象, 赋值给c++对象之后会出现乱码或者为空的问题. 是否有编译优化设置导致?

2、napi_get_value_string_utf8 只能读取已知长度字符串, 只能通过循环判断读取整个字符串长度?

cke_353.png

#include "napi/native_api.h"
#include <bits/alltypes.h>
#include <hilog/log.h>
#include <vector>
#include <string>
// #include "NemoSDKAdaptor.h"

const unsigned int LOG_PRINT_DOMAIN = 0xFF00;

struct Configs {
    const char *logFolder{""}; // 日志路径
    const char *name{""};      // 日志路径
};

class NemoSDKAdaptor {
public:
    NemoSDKAdaptor() {

    }
    NemoSDKAdaptor(napi_env env, napi_value thisVar) {

    }
    virtual ~NemoSDKAdaptor() {}

};

const char *LOG_PRINT_TAG = "NemoSDK";

std::string util_get_string_value(napi_env env, napi_value arg) {
    size_t len = 0;
    napi_get_value_string_utf8(env, arg, nullptr, 0, &len);   // 获取字符串长度到len
    char *buf = new char[len + 1];                            // 分配合适大小的char数组
    napi_get_value_string_utf8(env, arg, buf, len + 1, &len); // 获取字符串
    return buf;
}

std::string util_get_object_string_property_value(napi_env env, napi_value arg, const char *name) {
    napi_status status = napi_ok;
    napi_value js_result;
    status = napi_get_named_property(env, arg, name, &js_result);
    if (napi_ok == status) {
        std::string temp = util_get_string_value(env, js_result);
        return temp;
    }
    return "";
}

napi_value startup(napi_env env, napi_callback_info cbinfo) {
    size_t argc = 2;
    napi_value argv[2] = {0};

    napi_value thisVar = nullptr;
    void *data = nullptr;
    napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, &data);
//     NemoSDKAdaptor *sdkAdaptor = nullptr;
//     napi_unwrap(env, thisVar, (void **)&sdkAdaptor);

    {
        Configs configs;
        configs.logFolder = util_get_object_string_property_value(env, argv[0], "logFolder").c_str();
        configs.name = util_get_string_value(env, argv[1]).c_str();
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_PRINT_TAG, "logFolder_0 %{public}s, name: %{public}s", configs.logFolder, configs.name);
    }
    {
        Configs configs;
        std::string logFolder = util_get_object_string_property_value(env, argv[0], "logFolder");
        configs.logFolder = logFolder.c_str();
        configs.name = util_get_string_value(env, argv[1]).c_str();
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_PRINT_TAG, "logFolder_1 %{public}s, name: %{public}s", configs.logFolder, configs.name);
    }
    {
        Configs configs;
        configs.logFolder = util_get_object_string_property_value(env, argv[0], "logFolder").c_str();
        configs.name = util_get_string_value(env, argv[1]).c_str();
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_PRINT_TAG, "logFolder_2 %{public}s, name: %{public}s", configs.logFolder, configs.name);
    }

    return nullptr;
}

napi_value constructor(napi_env env, napi_callback_info info) {
    napi_value thisVar = nullptr;
    void *data = nullptr;
    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
    NemoSDKAdaptor *adaptor = new NemoSDKAdaptor(env, thisVar);
    napi_wrap(
        env, thisVar, adaptor,
        [](napi_env env, void *data, void *hint) {
            NemoSDKAdaptor *ada = (NemoSDKAdaptor *)data;
            delete ada;
        },
        nullptr, nullptr);

    return thisVar;
}

napi_value Export(napi_env env, napi_value exports) {
    const char className[] = "NemoSDKAdaptor";
    napi_property_descriptor properties[] = {
        {"startup", nullptr, startup, nullptr, nullptr, nullptr, napi_default, nullptr},
    };

    napi_value netServerClass = nullptr;
    napi_define_class(env, className, sizeof(className), constructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &netServerClass);
    napi_set_named_property(env, exports, "NemoSDKAdaptor", netServerClass);

    return exports;
};

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Export,
    .nm_modname = "entry",
    .nm_priv = ((void *)0),
    .reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }

【解决方案】

在char*转string的过程中有可能出现类型转换耗时的问题,导致乱码的出现,经测试把util_get_object_string_property_value()和util_get_object_string_property_value()的返回值都设成char*可以解决问题。

c++中 foo()返回std:string,当使用const char* str =foo().c_str(); 再去访问str,在这种情况下,问题在于`const char* str`指向的是`foo()`返回的`std::string`对象内部的字符数组的地址,而这个`std::string`对象是一个临时对象,其生命周期随着语句结束而结束。因此,一旦`foo()`函数返回后,临时对象会被销毁, str、指针指向的内存将变得无效,进而访问`str`可能会导致未定义的行为。所以建议直接改成返回char* 。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值