### Get File List Example (C++/NAPI) Source: https://github.com/chenqinggang001/napi-docs/blob/main/rawfile-guidelines.md Demonstrates iterating through raw files, creating JavaScript strings, and setting elements in a JavaScript array. It involves closing resource pointers. ```cpp napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); napi_set_element(env, fileList, i, jsString); } // 关闭打开的指针对象 OH_ResourceManager_CloseRawDir(rawDir); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); return fileList; } ``` -------------------------------- ### Get RawFile Content Example (C++/NAPI) Source: https://github.com/chenqinggang001/napi-docs/blob/main/rawfile-guidelines.md Provides an example of reading the entire content of a raw file. It initializes the resource manager, opens the file, reads its content into a buffer, and returns it as a JavaScript TypedArray (uint8_array). ```cpp // 示例二:获取rawfile文件内容 GetRawFileContent napi_value CreateJsArrayValue(napi_env env, std::unique_ptr &data, long length) { // 创建js外部ArrayBuffer napi_value buffer; napi_status status = napi_create_external_arraybuffer(env, data.get(), length, [](napi_env env, void *data, void *hint) { delete[] static_cast(data); }, nullptr, &buffer); // 检测ArrayBuffer是否创建成功 if (status != napi_ok) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create external array buffer"); return nullptr; } // 创建js TypedArray 将ArrayBuffer绑定到TypedArray napi_value result = nullptr; status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); if (status != napi_ok) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create media typed array"); return nullptr; } data.release(); return result; } static napi_value GetRawFileContent(napi_env env, napi_callback_info info) { OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "GetFileContent Begin"); size_t argc = 2; napi_value argv[2] = { nullptr }; // 获取参数信息 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); size_t strSize; char strBuf[256]; napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); std::string filename(strBuf, strSize); // 获取rawfile指针对象 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); if (rawFile != nullptr) { OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_ResourceManager_OpenRawFile success"); } // 获取rawfile大小并申请内存 long len = OH_ResourceManager_GetRawFileSize(rawFile); std::unique_ptr data = std::make_unique(len); // 一次性读取rawfile全部内容 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); // 关闭打开的指针对象 OH_ResourceManager_CloseRawFile(rawFile); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); // 转为js对象 return CreateJsArrayValue(env, data, len); } ``` -------------------------------- ### C++ Example: Setting and Getting JSVM Instance Data Source: https://github.com/chenqinggang001/napi-docs/blob/main/jsvm-data-types-interfaces.md A C++ code example demonstrating the initialization of a JSVM environment, setting custom instance data, and retrieving it. It includes necessary setup and teardown functions for the VM and environment. ```c++ JSVM_VM vm; JSVM_CreateVMOptions options; JSVM_VMScope vm_scope; JSVM_Env env; JSVM_EnvScope envScope; JSVM_HandleScope handlescope; static int aa = 0; struct InstanceData { int32_t value; }; // 初始化虚拟机,创建JSVM运行环境 void init_JSVM_environment(){ JSVM_InitOptions init_options; memset(&init_options, 0, sizeof(init_options)); if (aa == 0) { OH_JSVM_Init(&init_options); aa++; } memset(&options, 0, sizeof(options)); OH_JSVM_CreateVM(&options, &vm); OH_JSVM_OpenVMScope(vm, &vm_scope); OH_JSVM_CreateEnv(vm, 0, nullptr, &env); OH_JSVM_OpenEnvScope(env, &envScope); OH_JSVM_OpenHandleScope(env, &handlescope); } // 退出虚拟机,释放对应的环境 napi_value close_JSVM_environment(napi_env env1, napi_callback_info info) { OH_JSVM_CloseHandleScope(env, handlescope); OH_JSVM_CloseEnvScope(env, envScope); OH_JSVM_DestroyEnv(env); OH_JSVM_CloseVMScope(vm, vm_scope); OH_JSVM_DestroyVM(vm); napi_value result; char* s = "ok"; napi_create_string_latin1(env1, s, strlen(s), &result); return result; } //清除和释放与实例相关联的内存资源 void InstanceFinalizeCallback(JSVM_Env env, void *finalizeData, void *finalizeHint) { if (finalizeData) { InstanceData *data = reinterpret_cast(finalizeData); free(data); *(InstanceData **)finalizeData = nullptr; } } static napi_value GetInstanceData(napi_env env1, napi_callback_info info) { InstanceData *instanceData = reinterpret_cast(malloc(sizeof(InstanceData))); if (instanceData == nullptr) { printf("Memory allocation failed!\n"); return nullptr; } size_t argc = 1; napi_value args[1] = {nullptr}; //用于获取回调函数参数 napi_get_cb_info(env1, info, &argc, args , nullptr, nullptr); napi_valuetype valuetype0; napi_typeof(env1, args[0], &valuetype0); int32_t tmp = 0; napi_get_value_int32(env1, args[0], &tmp); instanceData->value = tmp; //将获得的参数与当前运行的JSVM环境关联起来 OH_JSVM_SetInstanceData(env, instanceData, InstanceFinalizeCallback, nullptr); InstanceData *resData = nullptr; //获取与当前运行的JSVM环境相关联的数据 OH_JSVM_GetInstanceData(env, (void **)&resData); napi_value result; napi_create_uint32(env1, resData->value, &result); return result; } ``` -------------------------------- ### Get RawFile Descriptor Example (C++/NAPI) Source: https://github.com/chenqinggang001/napi-docs/blob/main/rawfile-guidelines.md Demonstrates how to obtain a raw file descriptor, including file descriptor (fd), offset, and length. It converts these properties into a JavaScript object and returns it. ```cpp // 示例三:获取rawfile文件描述符 GetRawFileDescriptor // 定义一个函数,将RawFileDescriptor转为js对象 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor& descriptor) { // 创建js对象 napi_value result; napi_status status = napi_create_object(env, &result); if (status != napi_ok) { return result; } // 将文件描述符df存入到result对象中 napi_value fd; status = napi_create_int32(env, descriptor.fd, &fd); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "fd", fd); if (status != napi_ok) { return result; } // 将文件偏移量offset存入到result对象中 napi_value offset; status = napi_create_int64(env, descriptor.start, &offset); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "offset", offset); if (status != napi_ok) { return result; } // 将文件长度length存入到result对象中 napi_value length; status = napi_create_int64(env, descriptor.length, &length); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "length", length); if (status != napi_ok) { return result; } return result; } static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) { OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "NDKTest GetRawFileDescriptor Begin"); size_t argc = 2; napi_value argv[2] = { nullptr }; // 获取参数信息 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); ``` -------------------------------- ### C++ JSVM Environment Setup and Execution Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-create-snapshot.md This C++ code snippet initializes a JavaScript Virtual Machine (JSVM) environment, compiles and runs a JavaScript string, and then cleans up the environment scopes. It uses N-API for integration. ```cpp CHECK_RET(OH_JSVM_OpenEnvScope(env, &envScope)); CHECK_RET(OH_JSVM_OpenHandleScope(env, &handleScope)); // 通过script调用测试函数 JSVM_Script script; JSVM_Value jsSrc; CHECK_RET(OH_JSVM_CreateStringUtf8(env, srcCallNative, JSVM_AUTO_LENGTH, &jsSrc)); CHECK_RET(OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script)); CHECK_RET(OH_JSVM_RunScript(env, script, &result)); // 销毁JSVM环境 CHECK_RET(OH_JSVM_CloseHandleScope(env, handleScope)); CHECK_RET(OH_JSVM_CloseEnvScope(env, envScope)); CHECK(OH_JSVM_CloseVMScope(vm, vmScope)); CHECK(OH_JSVM_DestroyEnv(env)); CHECK(OH_JSVM_DestroyVM(vm)); return 0; } static napi_value RunTest(napi_env env, napi_callback_info info) { TestJSVM(); return nullptr; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { OH_LOG_INFO(LOG_APP, "JSVM Init"); napi_property_descriptor desc[] = { {"runTest", nullptr, RunTest, nullptr, nullptr, nullptr, napi_default, nullptr}, }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } EXTERN_C_END static napi_module demoModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "entry", .nm_priv = ((void *)0), .reserved = {0}, }; extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } ``` -------------------------------- ### C++ OpenMP Integration and NAPI Setup Source: https://github.com/chenqinggang001/napi-docs/blob/main/openmp-guideline.md Demonstrates integrating OpenMP into an OpenHarmony NDK project. It includes the `omp.h` header, uses the `#pragma omp parallel` directive for parallel execution, logs messages using `OH_LOG_INFO`, and registers a NAPI function `OmpTest`. ```cpp #include "napi/native_api.h" #include "omp.h" #include "hilog/log.h" #undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0x3200 // 全局domain宏,标识业务领域 #define LOG_TAG "MY_TAG" // 全局tag宏,标识模块日志tag static napi_value OmpTest(napi_env env, napi_callback_info info) { OH_LOG_INFO(LOG_APP, "=================Hello OpenMP test.===================="); #pragma omp parallel { OH_LOG_INFO(LOG_APP, "Hello OpenMP!"); } return nullptr; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { { "ompTest", nullptr, OmpTest, nullptr, nullptr, nullptr, napi_default, nullptr } }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } EXTERN_C_END static napi_module demoModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "entry", .nm_priv = ((void*)0), .reserved = { 0 }, }; extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } ``` -------------------------------- ### Get VM Instance Example (C++) Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-heapstatistics-debugger-cpuprofiler-heapsnapshot.md Demonstrates how to retrieve a JavaScript Virtual Machine (JSVM) instance using the OH_JSVM_GetVM API in C++. It includes error handling and logging for the operation. ```cpp // hello.cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // OH_JSVM_GetVM的样例方法 static JSVM_Value GetVM(JSVM_Env env, JSVM_CallbackInfo info) { // 获取当前虚拟机对象,后续可以进行与虚拟机相关的操作或分析 JSVM_VM testVm; JSVM_Status status = OH_JSVM_GetVM(env, &testVm); JSVM_Value result = nullptr; if (status != JSVM_OK || testVm == nullptr) { OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetVM: failed"); OH_JSVM_GetBoolean(env, true, &result); } else { OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetVM: success"); OH_JSVM_GetBoolean(env, false, &result); } return result; } // GetVM注册回调 static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetVM}, }; static JSVM_CallbackStruct *method = param; // GetVM方法别名,供JS调用 static JSVM_PropertyDescriptor descriptor[] = { {"getVM", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; ``` -------------------------------- ### hello.cpp 源码 Source: https://github.com/chenqinggang001/napi-docs/blob/main/build-with-ndk-cmake.md 演示工程的主入口文件,包含`main`函数,调用`sum`函数并输出结果。 ```cpp #include #include "sum.h" int main(int argc,const char **argv) { std::cout<< "hello world!" < threads; for (auto function : { good_write, bad_close }) { threads.emplace_back(function); } for (auto& thread : threads) { thread.join(); } } int main() { functional_test(); return 0; } ``` -------------------------------- ### JSVM Snapshot Execution Example Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-create-snapshot.md Demonstrates loading a previously created VM snapshot from a file and using it to create a JSVM environment and execute a script. This allows for faster VM initialization. ```cpp static void RunVMSnapshot() { // blobData的生命周期不能短于vm的生命周期 // 从文件中读取snapshot std::vector blobData; std::ifstream file("/data/storage/el2/base/files/test_blob.bin", std::ios::in | std::ios::binary | std::ios::ate); size_t blobSize = file.tellg(); blobData.resize(blobSize); file.seekg(0, std::ios::beg); file.read(blobData.data(), blobSize); file.close(); OH_LOG_INFO(LOG_APP, "Test JSVM RunVMSnapshot read file blobSize = : %{public}ld", blobSize); // 使用快照数据创建虚拟机实例 JSVM_VM vm; JSVM_CreateVMOptions vmOptions; memset(&vmOptions, 0, sizeof(vmOptions)); vmOptions.snapshotBlobData = blobData.data(); vmOptions.snapshotBlobSize = blobSize; OH_JSVM_CreateVM(&vmOptions, &vm); JSVM_VMScope vmScope; OH_JSVM_OpenVMScope(vm, &vmScope); // 从快照中创建环境env JSVM_Env env; OH_JSVM_CreateEnvFromSnapshot(vm, 0, &env); JSVM_EnvScope envScope; OH_JSVM_OpenEnvScope(env, &envScope); // 执行js脚本,快照记录的env中定义了createHelloString() std::string src = "createHelloString()"; JSVM_Value result = RunVMScript(env, src); // 环境关闭前检查脚本运行结果 char str[MAX_BUFFER_SIZE]; OH_JSVM_GetValueStringUtf8(env, result, str, MAX_BUFFER_SIZE, nullptr); if (strcmp(str, "Hello world!") != 0) { OH_LOG_ERROR(LOG_APP, "jsvm fail file: %{public}s line: %{public}d", __FILE__, __LINE__); } // 关闭并销毁环境和虚拟机 OH_JSVM_CloseEnvScope(env, envScope); OH_JSVM_DestroyEnv(env); OH_JSVM_CloseVMScope(vm, vmScope); OH_JSVM_DestroyVM(vm); return; } ``` -------------------------------- ### JSVM CreateStringUtf8 Example Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-about-string.md Illustrates creating a JavaScript string object from a UTF-8 encoded C++ string using OH_JSVM_CreateStringUtf8. The example provides C++ code for the creation process and JavaScript for invoking the native function, including error handling and logging. ```cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include #include // OH_JSVM_CreateStringUtf8的样例方法 static JSVM_Value CreateStringUtf8(JSVM_Env env, JSVM_CallbackInfo info) { const char *str = u8"你好, World!, successes to create 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"; ``` ```javascript let script = createStringUtf8(); ``` -------------------------------- ### CMake Build Configuration Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-event-loop.md This CMakeLists.txt file outlines the build process for the native module. It sets the minimum CMake version, defines the project name, includes necessary directories, and adds a shared library target named 'entry' compiled from 'hello.cpp'. It also links against the 'libace_napi.z.so' library, which is essential for N-API functionality. ```cmake # the minimum version of CMake. cmake_minimum_required(VERSION 3.4.1) project(myapplication) set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) if(DEFINED PACKAGE_FIND_FILE) include(${PACKAGE_FIND_FILE}) endif() include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) add_library(entry SHARED hello.cpp) target_link_libraries(entry PUBLIC libace_napi.z.so) ``` -------------------------------- ### C++ Example: OH_JSVM_CoerceToNumber Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-about-primitive.md Illustrates the usage of `OH_JSVM_CoerceToNumber` in C++ for converting JavaScript values to numbers. The example shows how to capture arguments, perform the coercion, handle potential errors, and extract the resulting integer value for logging. It also includes the necessary setup for registering the function as a native callable method. ```c++ #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // OH_JSVM_CoerceToNumber的样例方法 static JSVM_Value CoerceToNumber(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 number = nullptr; JSVM_Status status = OH_JSVM_CoerceToNumber(env, args[0], &number); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CoerceToNumber failed"); } else { int32_t result = 0; OH_JSVM_GetValueInt32(env, number, &result); OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CoerceToNumber success:%{public}d", result); } return number; } // CoerceToNumber注册回调 static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = CoerceToNumber}, }; static JSVM_CallbackStruct *method = param; // CoerceToNumber方法别名,ArkTS侧调用 static JSVM_PropertyDescriptor descriptor[] = { {"coerceToNumber", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // 样例测试js const char *srcCallNative = R"JS(coerceToNumber(true))JS"; ``` ```javascript coerceToNumber(true) ``` -------------------------------- ### Node-API Instance Data Set/Get Examples Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-about-crash.md Provides examples for `napi_set_instance_data` and `napi_get_instance_data`, which are used to store and retrieve data associated with the N-API environment instance. This is useful for managing addon-specific state or configuration. ```cpp /* * 接口声明 index.d.ts * const triggerDFXInsSetXT: () => void; */ napi_value TriggerDFXInsSetXT(napi_env env, napi_callback_info) { std::thread([](napi_env env) { napi_set_instance_data(env, nullptr, [](napi_env, void *, void *) {}, nullptr); }, env).join(); return nullptr; } ``` ```cpp /* * 接口声明 index.d.ts * const triggerDFXInsGetXT: () => void; */ napi_value TriggerDFXInsGetXT(napi_env env, napi_callback_info) { std::thread([](napi_env env) { void *data = nullptr; napi_get_instance_data(env, &data); }, env).join(); return nullptr; } ``` -------------------------------- ### Correct OH_JSVM_GetCbInfo: Getting Argument Count and Values Source: https://github.com/chenqinggang001/napi-docs/blob/main/jsvm-guidelines.md Demonstrates correct patterns for using `OH_JSVM_GetCbInfo`. The first example shows how to first determine the actual argument count by passing `nullptr` for `argv`, then allocating memory for `argv` based on the count. The second example shows pre-allocating `argv` with a known size. ```cpp static JSVM_Value GetArgvDemo1(napi_env env, JSVM_CallbackInfo info) { size_t argc = 0; // argv 传入 nullptr 来获取传入参数真实数量 OH_JSVM_GetCbInfo(env, info, &argc, nullptr, nullptr, nullptr); // JS 传入参数为0,不执行后续逻辑 if (argc == 0) { return nullptr; } // 创建数组用以获取JS传入的参数 JSVM_Value* argv = new JSVM_Value[argc]; OH_JSVM_GetCbInfo(env, info, &argc, argv, nullptr, nullptr); // 业务代码 // ... ... // argv 为 new 创建的对象,在使用完成后手动释放 delete argv; return nullptr; } ``` ```cpp static JSVM_Value GetArgvDemo2(napi_env env, JSVM_CallbackInfo info) { size_t argc = 2; JSVM_Value* argv[2] = {nullptr}; // OH_JSVM_GetCbInfo 会向 argv 中写入 argc 个 JS 传入参数或 undefined OH_JSVM_GetCbInfo(env, info, &argc, nullptr, nullptr, nullptr); // 业务代码 // ... ... return nullptr; } ``` -------------------------------- ### CMake配置Neon扩展 Source: https://github.com/chenqinggang001/napi-docs/blob/main/neon-guide.md 此代码片段展示了如何在CMakeLists.txt文件中为armeabi-v7a架构配置编译选项,以启用ARM Neon扩展。通过设置-mfpu=neon和-mfloat-abi=softfp编译器标志,确保Neon指令集被正确利用。 ```Makefile if (${OHOS_ARCH} STREQUAL "armeabi-v7a") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mfloat-abi=softfp") endif () ``` -------------------------------- ### Read PurgeableMemory Object Source: https://github.com/chenqinggang001/napi-docs/blob/main/purgeable-memory-guidelines.md Illustrates how to perform a read operation on a PurgeableMemory object, including getting its size and content, and properly ending the read access. ```c++ class ReqObj; if(OH_PurgeableMemory_BeginRead(pPurgmem)) { size_t size = OH_PurgeableMemory_ContentSize(pPurgmem); ReqObj* pReqObj = (ReqObj*) OH_PurgeableMemory_GetContent(pPurgmem); OH_PurgeableMemory_EndRead(pPurgmem); } ``` -------------------------------- ### OpenHarmony Build Profile Configuration Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-event-loop.md This JSON configuration snippet is part of the `build-profile.json5` file for an OpenHarmony project. It specifies build options, particularly for ArkTS, by defining `runtimeOnly` sources. This ensures that the specified ArkTS files, such as './src/main/ets/pages/ObjectUtils.ets', are correctly included and processed during the build, making them available for the native module. ```json { "buildOption" : { "arkOptions" : { "runtimeOnly" : { "sources": [ "./src/main/ets/pages/ObjectUtils.ets" ] } } } } ``` -------------------------------- ### ArkTS Example for Get Array Length Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-about-array.md Demonstrates how to call the Node-API `getArrayLength` function from ArkTS. It logs the array length using hilog, showing the integration between ArkTS and native Node-API modules. ```arkts import hilog from '@ohos.hilog'; import testNapi from 'libentry.so'; const arr = [0, 1, 2, 3, 4, 5]; hilog.info(0x0000, 'testTag', 'Test Node-API get_array_length:%{public}d', testNapi.getArrayLength(arr)); ``` -------------------------------- ### JSVM Snapshot Creation Example Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-create-snapshot.md Illustrates how to create a JavaScript Virtual Machine (VM) instance, configure it for snapshotting, register native functions, and generate a VM snapshot blob. The snapshot is then saved to a file. ```cpp static void CreateVMSnapshot() { // 创建JavaScript虚拟机实例,打开虚拟机作用域 JSVM_VM vm; JSVM_CreateVMOptions vmOptions; memset(&vmOptions, 0, sizeof(vmOptions)); // isForSnapshotting设置该虚拟机是否用于创建快照 vmOptions.isForSnapshotting = true; OH_JSVM_CreateVM(&vmOptions, &vm); JSVM_VMScope vmScope; OH_JSVM_OpenVMScope(vm, &vmScope); // 创建JavaScript环境,打开环境作用域 JSVM_Env env; // 将native函数注册成JavaScript可调用的方法 JSVM_PropertyDescriptor descriptor[] = { {"createHelloString", nullptr, &helloCb, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; OH_JSVM_CreateEnv(vm, 1, descriptor, &env); JSVM_EnvScope envScope; OH_JSVM_OpenEnvScope(env, &envScope); // 使用OH_JSVM_CreateSnapshot创建虚拟机的启动快照 const char *blobData = nullptr; size_t blobSize = 0; JSVM_Env envs[1] = {env}; OH_JSVM_CreateSnapshot(vm, 1, envs, &blobData, &blobSize); // 将snapshot保存到文件中 // 保存快照数据,/data/storage/el2/base/files/test_blob.bin为沙箱路径 // 以包名为com.example.jsvm为例,实际文件会保存到/data/app/el2/100/base/com.example.jsvm/files/test_blob.bin std::ofstream file( "/data/storage/el2/base/files/test_blob.bin", std::ios::out | std::ios::binary | std::ios::trunc); file.write(blobData, blobSize); file.close(); // 关闭并销毁环境和虚拟机 OH_JSVM_CloseEnvScope(env, envScope); OH_JSVM_DestroyEnv(env); OH_JSVM_CloseVMScope(vm, vmScope); OH_JSVM_DestroyVM(vm); } ``` -------------------------------- ### 子目录CMakeLists.txt Source: https://github.com/chenqinggang001/napi-docs/blob/main/build-with-ndk-cmake.md src目录下的CMakeLists.txt文件,定义了源文件、编译选项、库目标(动态库)和可执行目标,并指定了头文件包含路径和链接库。 ```cmake SET(LIBHELLO_SRC hello.cpp) # 设置编译参数 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") # 设置链接参数,具体参数可以忽略,纯粹为了举例 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--emit-relocs --verbose") # 添加一个libsum动态库目标,编译成功会生成一个libsum.so ADD_LIBRARY(sum SHARED sum.cpp) # 生成可执行程序,添加一个Hello的可执行程序目标,编译成功会生成一个Hello可执行程序 ADD_EXECUTABLE(Hello ${LIBHELLO_SRC}) # 指定Hello目标include目录路径 TARGET_INCLUDE_DIRECTORIES(Hello PUBLIC ../include) # 指定Hello目标需要链接的库名字 TARGET_LINK_LIBRARIES(Hello PUBLIC sum) ``` -------------------------------- ### OH JSVM GetNull: Get JavaScript Null Value Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-about-primitive.md Provides a method to obtain the JavaScript `null` value using OH_JSVM_GetNull. The example includes error checking to confirm successful retrieval of the null value. ```cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // OH_JSVM_GetNull的样例方法 static JSVM_Value GetNull(JSVM_Env env, JSVM_CallbackInfo info) { JSVM_Value nullValue = nullptr; JSVM_Status status = OH_JSVM_GetNull(env, &nullValue); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetNull fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetNull success"); } return nullValue; } // GetNull注册回调 static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetNull}, }; static JSVM_CallbackStruct *method = param; // GetNull方法别名,供JS调用 static JSVM_PropertyDescriptor descriptor[] = { {"getNull", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // 样例测试js const char *srcCallNative = R"JS(getNull())JS"; ``` ```javascript getNull() ``` -------------------------------- ### TypeScript Main Thread Worker Initialization Source: https://github.com/chenqinggang001/napi-docs/blob/main/napi-faq-about-memory-leak.md Example of initializing a worker thread from the main thread using TypeScript, as mentioned in the context of asynchronous operations for Node-API (N-API) development. ```typescript // 主线程 Index.ets import worker, { MessageEvents } from '@ohos.worker'; ``` -------------------------------- ### Native Memory Leak: Unbalanced OH_JSVM_CreateReference/DeleteReference Source: https://github.com/chenqinggang001/napi-docs/blob/main/jsvm-locate-memory-leak.md Example demonstrating a common Native memory leak scenario where OH_JSVM_CreateReference is called but OH_JSVM_DeleteReference is not. This leads to unreleased references, causing memory to accumulate. ```c++ JSVM_Value obj = nullptr; OH_JSVM_CreateObject(env, &obj); // 创建引用 JSVM_Ref reference; OH_JSVM_CreateReference(env, obj, 1, &reference); // 使用引用 JSVM_Value result; OH_JSVM_GetReferenceValue(env, reference, &result); // 未释放引用 // OH_JSVM_DeleteReference(env, reference); ``` -------------------------------- ### Load ohpm Package (axios) Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-load-module.md Demonstrates loading an ohpm package (e.g., @ohos/axios) using napi_load_module. Requires configuration in oh-package.json5 and build-profile.json5. ```json { "dependencies": { "@ohos/axios": "2.2.4" } } ``` ```json { "buildOption" : { "arkOptions" : { "runtimeOnly" : { "packages": [ "@ohos/axios" ] } } } } ``` ```cpp static napi_value loadModule(napi_env env, napi_callback_info info) { napi_value result; // 1. 使用napi_load_module加载@ohos/axios napi_status status = napi_load_module(env, "@ohos/axios", &result); if (status != napi_ok) { return nullptr; } // Further interaction with the loaded module would follow here. return result; } ``` -------------------------------- ### Get ArkTS String as UTF-16 (C++, TS) Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-about-string.md Demonstrates how to retrieve a string value from ArkTS and convert it to a UTF-16 encoded C++ string using Node-API. Includes C++ implementation, TypeScript interface, and ArkTS usage example. ```cpp #include "napi/native_api.h" // 定义字符串缓冲区的最大长度 static const int MAX_BUFFER_SIZE = 128; static napi_value GetValueStringUtf16(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); napi_value result = nullptr; // 字符串的缓冲区 char16_t buffer[MAX_BUFFER_SIZE]; // 字符串的缓冲区大小 size_t bufferSize = MAX_BUFFER_SIZE; // 字符串的长度 size_t stringLen; // 获取字符串的数据和长度 napi_get_value_string_utf16(env, args[0], buffer, bufferSize, &stringLen); // 获取字符串返回结果 napi_create_string_utf16(env, buffer, stringLen, &result); // 返回结果 return result; } ``` ```typescript // index.d.ts export const getValueStringUtf16: (data: string) => string; ``` ```typescript import hilog from '@ohos.hilog'; import testNapi from 'libentry.so'; let result = testNapi.getValueStringUtf16('hello,'); hilog.info(0x0000,'testTag','Node-API napi_get_value_string_utf16:%{public}s', result); ``` -------------------------------- ### 配置macOS环境变量 Source: https://github.com/chenqinggang001/napi-docs/blob/main/build-with-ndk-cmake.md 在macOS系统中,将OpenHarmony NDK的CMake工具添加到PATH环境变量。这通常通过编辑用户目录下的`.bash_profile`文件并执行`source`命令来完成。 ```bash #在当前用户目录下,打开 .bash_profile 文件,文件如果不存在,创建即可 vim ~/.bash_profile #在文件最后添加 cmake 路径,该路径是自己的放置文件的路径,之后保存退出 export PATH=${实际SDK路径}/native/build-tools/cmake/bin:$PATH #在命令行执行 source ~/.bash_profile 使环境变量生效 source ~/.bash_profile ``` -------------------------------- ### 配置Linux环境变量 Source: https://github.com/chenqinggang001/napi-docs/blob/main/build-with-ndk-cmake.md 在Linux系统中,将OpenHarmony NDK的CMake工具添加到PATH环境变量,以便在命令行中直接使用。需要编辑`.bashrc`文件并执行`source`命令使其生效。 ```bash # 打开.bashrc文件 vim ~/.bashrc # 在文件最后添加cmake路径,该路径是自己的放置文件的路径,之后保存退出 export PATH=${实际SDK路径}/native/build-tools/cmake/bin:$PATH # 在命令行执行source ~/.bashrc使环境变量生效 source ~/.bashrc ``` -------------------------------- ### C++ Example: Get Symbol.toStringTag using JSVM-API Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-about-well-known-symbols.md Demonstrates how to use `OH_JSVM_GetSymbolToStringTag` in C++ to retrieve the `Symbol.toStringTag` value. It evaluates a JavaScript string 'Symbol.toStringTag', retrieves the symbol via the API, and then strictly compares them, logging the result. ```cpp #include static JSVM_Value WellKnownSymbols(JSVM_Env env, JSVM_CallbackInfo info) { JSVM_VM vm; OH_JSVM_GetVM(env, &vm); JSVM_HandleScope handleScope; OH_JSVM_OpenHandleScope(env, &handleScope); std::string src = R"JS(Symbol.toStringTag)JS"; JSVM_Value jsSrc; JSVM_Script script; JSVM_Value result1; OH_JSVM_CreateStringUtf8(env, src.c_str(), JSVM_AUTO_LENGTH, &jsSrc); OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script); OH_JSVM_RunScript(env, script, &result1); JSVM_Value result2; OH_JSVM_GetSymbolToStringTag(env, &result2); bool is_equals = false; OH_JSVM_StrictEquals(env, result1, result2, &is_equals); OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetSymbolToStringTag result is correct : %{public}d\n", is_equals); OH_JSVM_CloseHandleScope(env, handleScope); return nullptr; } static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = WellKnownSymbols}, }; static JSVM_CallbackStruct *method = param; // wellKnownSymbols方法别名,供JS调用 static JSVM_PropertyDescriptor descriptor[] = { {"wellKnownSymbols", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // 样例测试JS const char *srcCallNative = R"JS(wellKnownSymbols();)JS"; ``` -------------------------------- ### OpenHarmony Rawfile Native API Source: https://github.com/chenqinggang001/napi-docs/blob/main/rawfile-guidelines.md 提供了一系列用于在OpenHarmony应用中管理Rawfile目录和文件的Native C/C++接口。这些接口支持初始化资源管理器、打开和关闭目录/文件、获取文件列表、读取文件内容、获取文件大小以及获取文件描述符等操作。部分接口提供了支持大于2GB文件的64位版本。 ```APIDOC NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) - Initializes native resource manager. - Parameters: - env: The napi_env environment. - jsResMgr: The napi_value representing the JavaScript resource manager. - Returns: A pointer to the initialized NativeResourceManager. ``` ```APIDOC RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) - Opens a specified rawfile directory. - Parameters: - mgr: Pointer to the NativeResourceManager. - dirName: The name of the rawfile directory to open. - Returns: A pointer to the RawDir structure if successful, otherwise NULL. ``` ```APIDOC int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) - Gets the number of rawfile files within a specified rawfile directory. - Parameters: - rawDir: Pointer to the RawDir structure. - Returns: The count of rawfile files in the directory. ``` ```APIDOC const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) - Gets the name of a rawfile at a specific index within a directory. - Parameters: - rawDir: Pointer to the RawDir structure. - index: The index of the file name to retrieve. - Returns: A pointer to the file name string, or NULL if the index is out of bounds. ``` ```APIDOC RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) - Opens a specified rawfile file. - Parameters: - mgr: Pointer to the NativeResourceManager. - fileName: The name of the rawfile file to open. - Returns: A pointer to the RawFile structure if successful, otherwise NULL. ``` ```APIDOC long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) - Gets the size of a rawfile file. - Parameters: - rawFile: Pointer to the RawFile structure. - Returns: The size of the file in bytes. ``` ```APIDOC int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) - Reads content from a rawfile file. - Parameters: - rawFile: Pointer to the RawFile structure. - buf: Buffer to store the read content. - length: The number of bytes to read. - Returns: The number of bytes actually read. ``` ```APIDOC void OH_ResourceManager_CloseRawFile(RawFile *rawFile) - Releases resources associated with a rawfile file. - Parameters: - rawFile: Pointer to the RawFile structure to close. ``` ```APIDOC void OH_ResourceManager_CloseRawDir(RawDir *rawDir) - Releases resources associated with a rawfile directory. - Parameters: - rawDir: Pointer to the RawDir structure to close. ``` ```APIDOC bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) - Gets the file descriptor (fd) of a rawfile. - Parameters: - rawFile: Pointer to the RawFile structure. - descriptor: A reference to RawFileDescriptor to be populated with fd and other info. - Returns: True if the file descriptor was successfully retrieved, false otherwise. ``` ```APIDOC void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) - Releases resources associated with the native resource manager. - Parameters: - resMgr: Pointer to the NativeResourceManager to release. ``` ```APIDOC bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path) - Checks if a given path within rawfile is a directory. - Parameters: - mgr: Pointer to the NativeResourceManager. - path: The path to check. - Returns: True if the path is a directory, false otherwise. ``` ```APIDOC RawDir *OH_ResourceManager_OpenRawDir64(const NativeResourceManager *mgr, const char *dirName) - Opens a specified rawfile directory, supporting larger directories. - Parameters: - mgr: Pointer to the NativeResourceManager. - dirName: The name of the rawfile directory to open. - Returns: A pointer to the RawDir structure if successful, otherwise NULL. ``` ```APIDOC RawFile *OH_ResourceManager_OpenRawFile64(const NativeResourceManager *mgr, const char *fileName) - Opens a specified rawfile file, supporting larger files (over 2GB). - Parameters: - mgr: Pointer to the NativeResourceManager. - fileName: The name of the rawfile file to open. - Returns: A pointer to the RawFile structure if successful, otherwise NULL. ``` -------------------------------- ### OH JSVM GetGlobal: Get JavaScript Global Object Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-jsvm-about-primitive.md Retrieves the global JavaScript object using OH_JSVM_GetGlobal, allowing interaction with the JavaScript runtime's global scope. The example demonstrates setting a property on this global object. ```cpp #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include // OH_JSVM_GetGlobal的样例方法 static JSVM_Value GetGlobal(JSVM_Env env, JSVM_CallbackInfo info) { // 获取全局对象 JSVM_Value value = nullptr; JSVM_Value global = nullptr; OH_JSVM_CreateInt32(env, 1, &value); JSVM_Status status = OH_JSVM_GetGlobal(env, &global); OH_JSVM_SetNamedProperty(env, global, "Row", value); if (status != JSVM_OK) { OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetGlobal fail"); } else { OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetGlobal success"); } return global; } // GetGlobal注册回调 static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = GetGlobal}, }; static JSVM_CallbackStruct *method = param; // GetGlobal方法别名,供JS调用 static JSVM_PropertyDescriptor descriptor[] = { {"getGlobal", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; // 样例测试js const char *srcCallNative = R"JS(getGlobal())JS"; ``` ```javascript getGlobal() ``` -------------------------------- ### Get Value String Latin1 (C++, APIDOC, TS) Source: https://github.com/chenqinggang001/napi-docs/blob/main/use-napi-about-string.md Converts ArkTS character data to ISO-8859-1 encoded characters. Handles string input and returns a C++ char buffer. Includes API definition and ArkTS usage examples. ```cpp #include "napi/native_api.h" static const int MAX_BUFFER_SIZE = 128; static napi_value GetValueStringLatin1(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); char buf[MAX_BUFFER_SIZE]; size_t length = 0; napi_value napi_Res = nullptr; napi_status status = napi_get_value_string_latin1(env, args[0], buf, MAX_BUFFER_SIZE, &length); // 当输入的值不是字符串时,接口会返回napi_string_expected if (status == napi_string_expected) { return nullptr; } napi_create_string_latin1(env, buf, length, &napi_Res); return napi_Res; } ``` ```APIDOC export const getValueStringLatin1: (param: number | string) => string | void; ``` ```typescript import hilog from '@ohos.hilog'; import testNapi from 'libentry.so'; // 传入非字符型数据,函数返回undefined hilog.info(0x0000, 'testTag', 'Test Node-API get_value_string_latin1_not_string %{public}s', testNapi.getValueStringLatin1(10)); // ISO-8859-1编码不支持中文,传入中文字符会乱码 hilog.info(0x0000, 'testTag', 'Test Node-API get_value_string_latin1_string_chinese %{public}s', testNapi.getValueStringLatin1('中文')); // 传入其他字符,不会乱码 hilog.info(0x0000, 'testTag', 'Test Node-API get_value_string_latin1_string %{public}s', testNapi.getValueStringLatin1('abo ABP=-&*/')); ```