【关键字】
赋值c++对象 / 乱码
【问题描述】
1、NAPI读取js字符串对象, 赋值给c++对象之后会出现乱码或者为空的问题. 是否有编译优化设置导致?
2、napi_get_value_string_utf8 只能读取已知长度字符串, 只能通过循环判断读取整个字符串长度?
#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* 。