鸿蒙(API 12 Beta2版)NDK开发【使用Node-API扩展能力接口】

news2024/9/20 14:48:37

简介

[扩展能力接口]进一步扩展了Node-API的功能,提供了一些额外的接口,用于在Node-API模块中与ArkTS进行更灵活的交互和定制,这些接口可以用于创建自定义ArkTS对象等场景。

Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程],本文仅对接口对应C++及ArkTS相关代码进行展示。

模块加载

接口描述

接口描述
napi_load_module用于在Node-API模块中将abc文件作为模块加载,返回模块的命名空间,适用于需要在运行时动态加载模块或资源的应用程序,从而实现灵活的扩展和定制。
napi_load_module_with_info用于在Node-API中进行模块的加载,当模块加载出来之后,可以使用函数napi_get_property获取模块导出的变量,也可以使用napi_get_named_property获取模块导出的函数,该函数可以在[新创建的ArkTs基础运行时环境]中使用
napi_module_register有些功能可能需要通过Node-API模块来实现以获得更好的性能,通过将这些功能实现为自定义模块并注册到ArkTS环境中,可以在一定程度上提高整体的性能。

使用示例

napi_load_module

[使用Node-API接口在主线程中进行模块加载]

napi_load_module_with_info

[使用Node-API接口进行模块加载]

napi_module_register

在ArkTS代码环境中使用Node-API模块编写的代码来实现特定的功能,可以将这部分功能封装成自定义模块,然后通过napi_module_register将其注册到ArkTS代码环境中,以实现功能的扩展和复用。

cpp部分代码

#include "napi/native_api.h"

// 此模块是一个Node-API的回调函数
static napi_value Add(napi_env env, napi_callback_info info)
{
    // 接受传入两个参数
    size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);

    // 将传入的napi_value类型的参数转化为double类型
    double valueLift;
    double valueRight;
    napi_get_value_double(env, args[0], &valueLift);
    napi_get_value_double(env, args[1], &valueRight);

    // 将转化后的double值相加并转成napi_value返回给ArkTS代码使用
    napi_value sum;
    napi_create_double(env, valueLift + valueRight, &sum);

    return sum;
}

// C++函数Init用于初始化插件,用于将ArkTS层的函数或属性与C++层的函数进行关联
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    // 通过napi_property_descriptor结构体,可以定义需要导出的属性,并在Node-API模块中使用。napi_define_properties将属性与实际的C++函数进行关联,使其可以被ArkTS层访问和调用
    napi_property_descriptor desc[] = {
        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

// 插件的初始化被定义在一个名为demoModule的结构体中,其中包含了模块的基本信息,比如模块的版本号、注册函数等
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 },
};

// 在RegisterEntryModule函数中,使用napi_module_register函数注册并导出了这个插件
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
    napi_module_register(&demoModule);
}

接口声明

// index.d.ts
export const add: (a: number, b: number) => number;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

hilog.info(0x0000, 'testTag', 'Test Node-API 2 + 3 = %{public}d', testNapi.add(2, 3));

ArkTS Object相关

接口描述

接口描述
napi_create_object_with_properties用于在Node-API模块中使用给定的napi_property_descriptor创建ArkTS Object。descriptor的键名必须为string,且不可转为number。
napi_create_object_with_named_properties用于在Node-API模块中使用给定的napi_value和键名创建ArkTS Object。键名必须为string,且不可转为number。

使用示例

napi_create_object_with_properties

用于使用给定的napi_property_descriptor作为属性去创建一个ArkTS对象,并且descriptor的键名必须为string,且不可转为number。

cpp部分代码

#include "napi/native_api.h"

static napi_value CreateObjectWithProperties(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value argv[1] = nullptr;
    // 获取解析传递的参数
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    // 声明了一个napi_property_descriptor数组desc,其中包含了一个名为"name"的属性,其值为传入的第一个参数argv[0]。
    napi_property_descriptor desc[] = {
        {"name", nullptr, nullptr, nullptr, nullptr, argv[0], napi_default_jsproperty, nullptr}};
    napi_value object = nullptr;
    // 调用napi_create_object_with_properties来创建一个新的ArkTS对象,并将属性值添加到该对象中。
    napi_create_object_with_properties(env, &object, sizeof(desc) / sizeof(desc[0]), desc);
    napi_valuetype valueType;
    napi_typeof(env, object, &valueType);
    if (valueType == napi_object) {
        return object;
    }
}

接口声明

// index.d.ts
export const createObjectWithProperties: (data: string) => Object;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.createObjectWithProperties('createObject');
hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_properties:%{public}s', JSON.stringify(value));

napi_create_object_with_named_properties

用于使用给定的napi_value和键名创建一个ArkTS对象,并且给定的键名必须为string,且不可转为number。

cpp部分代码

#include "napi/native_api.h"

static napi_value CreateObjectWithNameProperties(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value argv[1] = nullptr;
    // 获取解析传递的参数
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    napi_value obj = nullptr;
    const char *key[] = {
        "name",
    };
    const napi_value values[] = {
        argv[0],
    };
    napi_property_descriptor desc[] = {{"name", nullptr, nullptr,
                                        nullptr, nullptr, nullptr, napi_default, nullptr}};
    napi_status status;
    status = napi_create_object_with_named_properties(env, &obj, sizeof(desc) / sizeof(desc[0]), key, values);
    if (status != napi_ok) {
        return argv[0];
    }
    return obj;
}

接口声明

// index.d.ts
export const createObjectWithNameProperties: (data: string) => string | { name: string };

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.createObjectWithNameProperties('ls');
hilog.info(0x0000, 'testTag', 'Node-API napi_create_object_with_named_properties:%{public}s', JSON.stringify(value));

运行指定abc文件

接口描述

接口描述
napi_run_script_path用于在Node-API模块中运行指定abc文件。

使用示例

napi_run_script_path

在Node-API模块中运行abc文件。

cpp部分代码

#include "napi/native_api.h"

static napi_value RunScriptPath(napi_env env, napi_callback_info info)
{
    napi_value value = nullptr;
    // 注意:记得在应用rawfile目录下放置.abc文件
    const char *scriptPath = "/entry/resources/rawfile/test.abc";
    // 使用napi_run_script_path函数执行指定路径中的文件
    napi_status status = napi_run_script_path(env, scriptPath, &value);
    // 检查是否执行成功,如果失败,返回false
    napi_value returnValue = nullptr;
    if (value == nullptr || status != napi_ok) {
        napi_get_boolean(env, false, &returnValue);
    }
    napi_get_boolean(env, true, &returnValue);
    return returnValue;
}

接口声明

// index.d.ts
export const runScriptPath: () => boolean;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

try {
  // 在此处执行错误返回false,成功就返回true
  hilog.info(0x0000, 'testTag', 'Test Node-API napi_run_script_path: %{public}s', testNapi.runScriptPath());
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi_run_script_path errorMessage: %{public}s', error.message);
}

test.js代码,将js代码编成.abc文件,步骤如下:

  1. 在sdK的ets/build-tools/ets-loader/bin/ark/build-win/bin目录下放置test.js文件
  2. 执行命令如es2abc.exe test.js --output test.abc后便可生成test.abc文件

放入指定路径中:/entry/resources/rawfile

function add(a, b) {
  return a+b;
}
add(1, 2);

异步工作对象加入队列并指定优先级

接口描述

接口描述
napi_queue_async_work_with_qos用于将异步工作对象加入队列,让开发者能够根据QoS优先级来管理和调度异步工作的执行,从而更好地满足程序的性能和响应需求。

使用示例

napi_queue_async_work_with_qos

将异步工作对象加到队列,由底层根据传入的qos优先级去调度执行。

给ArkTS对象绑定回调和回调所需的参数

接口描述

接口描述
napi_coerce_to_native_binding_object用于给ArkTS对象绑定回调和回调所需的参数,其作用是为了给ArkTS对象携带Native信息。

使用示例

napi_coerce_to_native_binding_object

用于给ArkTS Object绑定回调和回调所需的参数,给ArkTS Object携带Native信息。

cpp部分代码

#include "napi/native_api.h"

// 解绑回调,在序列化时调用,可在对象解绑时执行一些清理操作
static void *DetachCb(napi_env env, void *nativeObject, void *hint)
{
    OH_LOG_INFO(LOG_APP, "Node-API this is detach callback");
    return nativeObject;
}

// 绑定回调,在反序列化时调用
static napi_value AttachCb(napi_env env, void *nativeObject, void *hint)
{
    OH_LOG_INFO(LOG_APP, "Node-API this is attach callback");
    napi_value object = nullptr;
    napi_value name = nullptr;
    // hint: 一个指针,可以用于传递附加的信息给回调函数
    // 在这里判断hint是否为空
    if (hint != nullptr) {
        // 将void*类型的nativeObject类型强转为napi_value的object
        object = reinterpret_cast<napi_value>(nativeObject);
        // 设置name属性
        napi_create_string_utf8(env, "Leili", NAPI_AUTO_LENGTH, &name);
    } else {
        napi_create_object(env, &object);
        // 设置name属性
        napi_create_string_utf8(env, "Hanmeimei", NAPI_AUTO_LENGTH, &name);
    }
    // 将Native的值设置到Javascript object中
    napi_set_named_property(env, object, "name", name);
    return object;
}

static napi_value CoerceToNativeBindingObject(napi_env env, napi_callback_info info)
{
    // 创建一个Javascript object
    napi_value object = nullptr;
    napi_create_object(env, &object);
    // 调用napi_coerce_to_native_binding_object给ArkTS Object携带Native信息
    napi_status status = napi_coerce_to_native_binding_object(env, object, DetachCb, AttachCb,
                                                              reinterpret_cast<void *>(object), nullptr);
    if (status != napi_ok) {
        napi_throw_error(env, nullptr, "Node-API napi_coerce_to_native_binding_object fail");
        return nullptr;
    }
    return object;
}

接口声明

// index.d.ts
export const coerceToNativeBindingObject: () => Object | void;

ArkTS侧示例代码

// index.ets
// 需要加入worker模块,这是为了触发序列化
import hilog from '@ohos.hilog'
import worker from '@ohos.worker';
import testNapi from 'libentry.so';

let wk = new worker.ThreadWorker("entry/ets/workers/worker.ts");
// 发送消息到worker线程
wk.postMessage("test napi_coerce_to_native_binding_object");
// 处理来自worker线程的消息
wk.onmessage = (message) => {
  hilog.info(0x0000, 'testTag', 'Test Node-API message from worker thread: %{public}s', JSON.stringify(message));
};
// worker.ts
// 处理来自主线程的消息
import worker from '@ohos.worker';
import testNapi from 'libentry.so'
import hilog from '@ohos.hilog'

let parent = worker.workerPort;
parent.onmessage = function(message) {
  hilog.info(0x0000, 'testTag', 'Test Node-API message from main thread: %{public}s', JSON.stringify(message));
  // 发送消息到主线程
  parent.postMessage(testNapi.coerceToNativeBindingObject());
}

注意事项

对ArkTs对象A调用napi_coerce_to_native_binding_object将开发者实现的detach/attach回调和native对象信息加到A上,再将A跨线程传递。跨线程传递需要对A进行序列化和反序列化,在当前线程thread1序列化A得到数据data,序列化阶段执行detach回调。然后将data传给目标线程thread2,在thread2中反序列化data,执行attach回调,最终得到ArkTS对象A’。

1

worker相关开发配置和流程参考以下链接:

[使用Worker进行线程间通信]

事件循环

接口描述

接口描述
napi_run_event_loop触发底层的事件循环。
napi_stop_event_loop停止底层的事件循环。

使用示例

napi_run_event_loop、napi_stop_event_loop

[使用扩展的Node-API接口在异步线程中运行和停止事件循环]

ArkTS基础运行时环境

接口描述

接口描述
napi_create_ark_runtime创建基础运行时环境。
napi_destroy_ark_runtime销毁基础运行时环境。

使用示例

napi_create_ark_runtime、napi_destroy_ark_runtime

[使用Node-API接口创建ArkTs运行时环境]

序列化和反序列化

接口描述

接口描述
napi_serialize将ArkTS对象转换为native数据。第一个参数env是接口执行的ArkTS环境;第二个参数object是待序列化的ArkTS对象;第三个参数transfer_list是存放需要以transfer传递的arrayBuffer的array,如不涉及可传undefined;第四个参数clone_list是存放需要克隆传递的Sendable对象的array,如不涉及可传undefined;第五个参数result是序列化结果。
napi_deserialize将native数据转为ArkTS对象。第一个参数env是接口执行的ArkTS环境;第二个参数buffer是序列化数据;第三个参数object是反序列化得到的结果。
napi_delete_serialization_data删除序列化数据。

使用示例

napi_serialize、napi_deserialize、napi_delete_serialization_data

用于将ArkTS对象转换为native数据、将native数据转为ArkTS对象、删除序列化数据等操作。

cpp部分代码

#include "napi/native_api.h"

static napi_value AboutSerialize(napi_env env, napi_callback_info info)
{
    // 获取传入的ts的一个对象作为参数
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    napi_value undefined = nullptr;
    // 构造napi_serialize方法所需参数
    napi_get_undefined(env, &undefined);
    void *data = nullptr;
    // 调用napi_serialize方法将ts对象转化为native数据
    napi_status status = napi_serialize(env, args[0], undefined, undefined, &data);
    if (status != napi_ok ||data == nullptr) {
        napi_throw_error(env, nullptr, "Node-API napi_serialize fail");
        return nullptr;
    }
    // 构造napi_value类型的数据,用于接收将native数据转化为ts对象后的数据
    napi_value result = nullptr;
    napi_deserialize(env, data, &result);
    napi_value number = nullptr;
    // 获取native数据转化为ts对象后的数据中的numKey属性的值
    napi_get_named_property(env, result, "numKey", &number);
    // 判断获取到的属性值是否为number类型
    napi_valuetype valuetype;
    napi_typeof(env, number, &valuetype);
    if (valuetype != napi_number) {
        napi_throw_error(env, nullptr, "Node-API Wrong type of argment. Expects a number.");
        return nullptr;
    }
    // 调用napi_delete_serialization_data方法删除序列化数据
    napi_delete_serialization_data(env, data);
    // 返回获取到的属性值
    return number;
}

接口声明

// index.d.ts
export const aboutSerialize: (obj: Object) => number;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'
class Obj {
  numKey:number = 0;
}
let obj: Obj = { numKey: 500 };
hilog.info(0x0000, 'testTag', ' Node-API aboutSerialize: %{public}d', testNapi.aboutSerialize(obj));

根据任务指定的优先级和入队方式进行处理异步线程向ArkTS线程投递的任务

接口描述

接口描述
napi_call_threadsafe_function_with_priority将指定优先级和入队方式的任务投递到ArkTS线程。

使用示例

napi_call_threadsafe_function_with_priority

[使用Node-API接口从异步线程向ArkTS线程投递指定优先级和入队方式的的任务]

Sendable相关

接口描述

接口描述
napi_is_sendable判断给定ArkTS value是否是Sendable的。
napi_define_sendable_class创建一个sendable类。
napi_create_sendable_object_with_properties使用给定的napi_property_descriptor创建一个sendable对象。
napi_create_sendable_array创建一个sendable数组。
napi_create_sendable_array_with_length创建一个指定长度的sendable数组。
napi_create_sendable_arraybuffer创建一个sendable ArrayBuffer。
napi_create_sendable_typedarray创建一个sendable TypedArray。
napi_wrap_sendable包裹一个native实例到ArkTS对象中。
napi_wrap_sendable_with_size包裹一个native实例到ArkTS对象中并指定大小。
napi_unwrap_sendable获取ArkTS对象包裹的native实例。
napi_remove_wrap_sendable移除并获取ArkTS对象包裹的native实例。

使用示例

napi_is_sendable

判断给定ArkTS value是否是Sendable的。

cpp部分代码

#include "napi/native_api.h"

static napi_value IsSendable(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);
    bool isSendable = false;
    napi_is_sendable(env, args[0], &isSendable);
    napi_value result;
    napi_get_boolean(env, isSendable, &result);
    return result;
}

接口声明

// index.d.ts
export const isSendable: <T>(a: T) => boolean;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.isSendable('createObject');
hilog.info(0x0000, 'testTag', 'Node-API napi_is_sendable: %{public}s', JSON.stringify(value));

napi_define_sendable_class

创建一个sendable类。

cpp部分代码

#include "napi/native_api.h"

static napi_value func(napi_env env, napi_callback_info info) {
    napi_value val;
    napi_create_string_utf8(env, "func result", NAPI_AUTO_LENGTH, &val);
    return val;
}

static napi_value DefineSendableClass(napi_env env) {
    napi_value str;
    napi_create_string_utf8(env, "str", NAPI_AUTO_LENGTH, &str);

    napi_property_descriptor props[] = {
        {"staticStr", nullptr, nullptr, nullptr, nullptr, str,
         static_cast<napi_property_attributes>(napi_static | napi_writable), nullptr},
        {"staticFunc", nullptr, func, nullptr, nullptr, nullptr, napi_static, nullptr},
        {"str", nullptr, nullptr, nullptr, nullptr, str, static_cast<napi_property_attributes>(1 << 9 | napi_writable),
         nullptr},
        {"func", nullptr, nullptr, nullptr, nullptr, nullptr,
         static_cast<napi_property_attributes>(1 << 11 | napi_writable), nullptr},
    };

    napi_value sendableClass = nullptr;
    napi_define_sendable_class(
        env, "SendableClass", NAPI_AUTO_LENGTH,
        [](napi_env env, napi_callback_info info) -> napi_value {
            napi_value thisVar = nullptr;
            napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
            napi_value str;
            napi_create_string_utf8(env, "instance str", NAPI_AUTO_LENGTH, &str);
            napi_property_descriptor props[] = {
                {"str", nullptr, nullptr, nullptr, nullptr, str, napi_default, nullptr},
                {"func", nullptr, func, nullptr, nullptr, nullptr, napi_default, nullptr},
            };
            napi_define_properties(env, thisVar, sizeof(props) / sizeof(props[0]), props);
            return thisVar;
        },
        nullptr, sizeof(props) / sizeof(props[0]), props, nullptr, &sendableClass);

    return sendableClass;
}

接口声明

// index.d.ts
@Sendable
export class SendableClass {
  static staticStr: string;
  static staticFunc(): string;
  str: string;
  func(): string;
}

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = new testNapi.SendableClass();
hilog.info(0x0000, 'testTag', 'Node-API napi_define_sendable_class: %{public}s', value.str);

napi_create_sendable_object_with_properties

使用给定的napi_property_descriptor创建一个sendable对象。

cpp部分代码

#include "napi/native_api.h"

static napi_value GetSendableObject(napi_env env, napi_callback_info info) {
    napi_value val_true;
    napi_get_boolean(env, true, &val_true);
    napi_property_descriptor desc1[] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
    };
    napi_value obj;
    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);
    return obj;
}

接口声明

// index.d.ts
export const getSendableObject: () => { x: true };

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.getSendableObject();
hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_object_with_properties: %{public}s', JSON.stringify(value));

napi_create_sendable_array

创建一个sendable数组。

cpp部分代码

#include "napi/native_api.h"

static napi_value GetSendableArray(napi_env env, napi_callback_info info) {
    napi_value result = nullptr;
    napi_create_sendable_array(env, &result);
    return result;
}

接口声明

// index.d.ts
export const getSendableArray: () => [];

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.getSendableArray();
hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array: %{public}s', JSON.stringify(value));

napi_create_sendable_array_with_length

创建一个指定长度的sendable数组。

cpp部分代码

static napi_value GetSendableArrayWithLength(napi_env env, napi_callback_info info) {
    napi_value result = nullptr;
    napi_create_sendable_array_with_length(env, 1, &result);
    return result;
}

接口声明

// index.d.ts
export const getSendableArrayWithLength: () => [];

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

let value = testNapi.getSendableArrayWithLength();
hilog.info(0x0000, 'testTag', 'Node-API napi_create_sendable_array_with_length: %{public}s', JSON.stringify(value.length));

napi_create_sendable_arraybuffer

创建一个sendable ArrayBuffer。

cpp部分代码

#include "napi/native_api.h"
#include "hilog/log.h"

static napi_value GetSendableArrayBuffer(napi_env env, napi_callback_info info) {
    static size_t LENGTH = 1024;
    void *data;
    napi_value result = nullptr;
    napi_create_sendable_arraybuffer(env, LENGTH, &data, &result);
    bool isArrayBuffer = false;
    napi_is_arraybuffer(env, result, &isArrayBuffer);
    OH_LOG_INFO(LOG_APP, "isArrayBuffer: %{public}d", isArrayBuffer);
    return result;
}

接口声明

// index.d.ts
export const getSendableArrayBuffer: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.getSendableArrayBuffer();

napi_create_sendable_typedarray

创建一个sendable TypedArray。

cpp部分代码

#include "napi/native_api.h"
#include "hilog/log.h"

static napi_value GetSendableTypedArray(napi_env env, napi_callback_info info) {
    static size_t LENGTH = 1024;
    static size_t OFFSET = 0;
    void *data;
    napi_value arraybuffer = nullptr;
    napi_create_sendable_arraybuffer(env, LENGTH, &data, &arraybuffer);

    napi_value result = nullptr;
    napi_create_sendable_typedarray(env, napi_uint8_array, LENGTH, arraybuffer, OFFSET, &result);
    bool isTypedArray = false;
    napi_is_typedarray(env, result, &isTypedArray);
    OH_LOG_INFO(LOG_APP, "isTypedArray: %{public}d", isTypedArray);
    return result;
}

接口声明

// index.d.ts
export const getSendableTypedArray: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.getSendableTypedArray();

napi_wrap_sendable

包裹一个native实例到ArkTS对象中。

cpp部分代码

#include "napi/native_api.h"

static napi_value WrapSendable(napi_env env, napi_callback_info info) {
    napi_value val_true;
    napi_get_boolean(env, true, &val_true);
    napi_property_descriptor desc1[] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
    };
    napi_value obj;
    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);

    const char* testStr = "test";
    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);
    
    return nullptr;
}

接口声明

// index.d.ts
export const wrapSendable: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.wrapSendable();

napi_wrap_sendable_with_size

包裹一个native实例到ArkTS对象中并指定大小。

cpp部分代码

#include "napi/native_api.h"

static napi_value WrapSendableWithSize(napi_env env, napi_callback_info info) {
    napi_value val_true;
    napi_get_boolean(env, true, &val_true);
    napi_property_descriptor desc1[] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
    };
    napi_value obj;
    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);

    const char* testStr = "test";
    napi_wrap_sendable_with_size(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr, 100);
    
    return nullptr;
}

接口声明

// index.d.ts
export const wrapSendableWithSize: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.wrapSendableWithSize();

napi_unwrap_sendable

获取ArkTS对象包裹的native实例。

cpp部分代码

#include "napi/native_api.h"

static napi_value UnwrapSendable(napi_env env, napi_callback_info info) {
    napi_value val_true;
    napi_get_boolean(env, true, &val_true);
    napi_property_descriptor desc1[] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
    };
    napi_value obj;
    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);

    const char* testStr = "test";
    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);

    char* tmpTestStr = nullptr;
    napi_unwrap_sendable(env, obj, (void**)&tmpTestStr);
    OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
    
    return nullptr;
}

接口声明

// index.d.ts
export const unwrapSendable: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.unwrapSendable();

napi_remove_wrap_sendable

移除并获取ArkTS对象包裹的native实例。

cpp部分代码

#include "napi/native_api.h"

static napi_value RemoveWrapSendable(napi_env env, napi_callback_info info) {
    napi_value val_true;
    napi_get_boolean(env, true, &val_true);
    napi_property_descriptor desc1[] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val_true, napi_default_jsproperty, nullptr},
    };
    napi_value obj;
    napi_create_sendable_object_with_properties(env, 1, desc1, &obj);

    const char* testStr = "test";
    napi_wrap_sendable(env, obj, (void*)testStr, [](napi_env env, void* data, void* hint) {}, nullptr);

    char* tmpTestStr = nullptr;
    napi_remove_wrap_sendable(env, obj, (void**)&tmpTestStr);
    OH_LOG_INFO(LOG_APP, "native value is %{public}s", tmpTestStr);
    
    return nullptr;
}

接口声明

// index.d.ts
export const removeWrapSendable: () => void;

ArkTS侧示例代码

import hilog from '@ohos.hilog'
import testNapi from 'libentry.so'

testNapi.removeWrapSendable();

以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include “hilog/log.h”):

// CMakeLists.txt
add_definitions( "-DLOG_DOMAIN=0xd0d0" )
add_definitions( "-DLOG_TAG=\"testTag\"" )
target_link_libraries(entry PUBLIC libhilog_ndk.z.so)

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1973012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

非负数、0和正整数 限制最大值且保留两位小数在elementpuls表单中正则验证

一、结构 <el-form-item label"单价&#xff1a;" prop"price"><el-inputv-model.trim"formData.price"placeholder"请输入"blur"formMethod.fixTwo"><template #append>(元)</template></el-i…

基础算法:离散化(C++实现)

文章目录 1. 离散化的定义2. 离散化例题2.1 离散化二分2.2 离散化哈希表 1. 离散化的定义 离散化是一种在程序设计和算法优化中常用的技术&#xff0c;其核心思想是将无限空间中有限的个体映射到有限的空间中去&#xff0c;以此提高算法的时空效率。具体来说&#xff0c;离散化…

Docker 安装 GitLab教程

本章教程,主要介绍如何在Docker 中安装GitLab。 GitLab 是一个开源的 DevOps 平台,提供了一整套工具,用于软件开发生命周期的各个阶段,从代码管理到 CI/CD(持续集成和持续交付/部署),再到监控和安全分析。 一、拉取镜像 docker pull gitlab/gitlab-ce:latest二、创建 G…

【React】探讨className的正确使用方式

文章目录 一、className的正确用法二、常见错误解析三、实例解析四、错误分析与解决五、注意事项六、总结 在React开发中&#xff0c;正确使用className属性对组件进行样式设置至关重要。然而&#xff0c;由于JavaScript和JSX的特殊性&#xff0c;开发者常常会犯一些小错误&…

ShardingSphere实战(2)- 水平分表

上篇博客&#xff0c;我们讲了 ShardingSphere实战&#xff08;1&#xff09;- 分库分表基础知识&#xff0c;这篇博客&#xff0c;正式开始实操。 项目环境&#xff1a; JDK11 MySQL 8.0.30 Springboot 2.7.4 Mybatis ShardingSphere HikariCP 连接池 一、Maven 依赖 <…

filebeat发送日志

filebeat: 1.可以在本机收集日志 2.也可以远程收集日志 3.轻量级的日志收集系统&#xff0c;可以在非Java环境运行 logstash是在jvm环境中运行&#xff0c;资源消耗很高&#xff0c;启动一个logstash需要消耗500M左右的内存 filebeat只消耗10M左右的内存 test3是装有logstash的…

C语言的内存布局

根据 C 语言的内存布局规律&#xff0c;通常局部变量和全局变量哪一个的地址更小&#xff1f; 答&#xff1a;如图所示。 下面代码中&#xff0c;为何两个不同的变量可以存放在同一个地址上&#xff1f; #include <stdio.h> void func1(void); void func2(void); voi…

安装 qcloud-python-sts 失败 提示 gbk codecs decode byte 应该如何解决

安装 qcloud-python-sts 失败 提示 gbk codecs decode byte 应该如何解决 解决方案&#xff1a; 将windows 修改为utf-8编码格式 解决步骤如下&#xff1a; 1. 进入控制台 2. 点击区域 4. 点击管理 4.勾选UTF-8 5.重启系统即可

Java零基础之多线程篇:线程间如何通信?

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

计算机技术基础 (bat 批处理)Note6

计算机技术基础 &#xff08;bat 批处理&#xff09;Note6 本节主要讲解FOR命令语句&#xff08;循环&#xff09;在 bat 批处理中的使用 (part 2) 变量延迟 命令语句 在没有开启变量延迟的情况下&#xff0c;批处理命令行中的变量改变&#xff0c;必须到下一条命令才能体现…

C++ STL在算法题中的常用语法

Vector 1.将vector<int>中的元素全部置换为0 fill(vec.begin(), vec.end(), 0); 2.vector容器是可以直接用比较是否值等的&#xff01; Unordered_set 1. unordered_set的删除&#xff08;count的值也会减少&#xff09; 2.unordered_map中的int默认值是0&#xff0c;…

Prometheus-v2.45.0+Grafana+邮件告警

目录 普罗米修斯监控架构介绍 Prometheus 监控架构 1. 数据抓取&#xff08;Scraping&#xff09; 2. 时序数据库&#xff08;TSDB&#xff09; 3. 数据模型 4. PromQL 查询语言 5. 告警&#xff08;Alerting&#xff09; 6. Alertmanager 7. 可视化&#xff08;Visu…

从0开始搭建vue + flask 旅游景点数据分析系统( 六):搭建后端flask框架

这一期开始开发header部分&#xff0c;预期实现两个目标&#xff1a; 创建 Flask 项目导入旅游数据后端实现旅游数据的查询 1 python 环境 & 开发环境 python 安装和pycharm安装需要去网上找包&#xff0c;建议python使用3.8 或者3.9版本 2 新建项目 我们新建一个文件…

Kafka详解以及常见kafka基本操作

1、 kafka 是什么,有什么作用 Kafka是一个开源的高吞吐量的分布式消息中间件&#xff0c;对比于缓冲和削峰&#xff1a;上游数据时有突发流量&#xff0c;下游可能扛不住&#xff0c;或者下游没有足够多的机器来保证冗余&#xff0c;kafka在中间可以起到一个缓冲的作用&#x…

Qt项目——文本编辑器(Bug/疑问)

项目地址&#xff1a;GitHub - Outlier9/CatEditor: Cat文本编辑器--Qt 有帮助的话各位点点 star 啦&#xff0c;感谢&#xff01; 如果有需要学习该项目的人&#xff0c;觉得看文档较为困难&#xff0c;可以加我联系方式&#xff0c;给github点个star后可免费提供学习视频&…

红酒与烹饪:美食的灵感之源

在烹饪的广阔天地中&#xff0c;红酒常常作为一道神秘的佐料&#xff0c;为菜肴带来别样的风味与深度。当定制红酒洒派红酒&#xff08;Bold & Generous&#xff09;与烹饪艺术相遇&#xff0c;一场美食的灵感之旅便悄然展开。 一、红酒与烹饪的浪漫邂逅 在烹饪的世界里&…

12月长沙学术会议:EI检索,机器人、自动化与智能控制方向

在春意盎然、生机勃勃的四月&#xff0c;全球科技界的目光聚焦于中国长沙&#xff0c;这里即将迎来一场科技与智慧碰撞的盛宴——第四届机器人、自动化与智能控制国际会议&#xff08;ICRAIC 2024&#xff09;。本次盛会由历史悠久、文化底蕴深厚的湖南第一师范学院荣耀主办&am…

正点原子imx6ull-mini-Linux驱动之platform设备驱动实验(14)

我们在前面几章编写的设备驱动都非常的简单&#xff0c;都是对IO进行最简单的读写操作像I2C、 SPI、LCD 等这些复杂外设的驱动就不能这么去写了&#xff0c;Linux 系统要考虑到驱动的可重用性&#xff0c;因此提出了驱动的分离与分层这样的软件思路&#xff0c;在这个思路下诞生…

QtQuick Text-文本样式

属性 Text项目的style属性可以设置文本的样式。 支持的文本样式有&#xff1a; Text.Normal&#xff08;默认&#xff09;Text.OutlineText.RaisedText.Sunken 示例 import QtQuickRow{spacing: 10padding: 10Text {font.pointSize: 40text: "Normal"}Text {font…

太阳光大约8分钟到达地球?太阳光:我一瞬间就到了!

我们常常听说,太阳光从太阳出发,需要8分钟才能抵达地球。这个时间听起来并不长,但它却是光子在宇宙空间中以惊人速度穿行的见证。 不过,这个8分钟的时间概念,实际上是站在我们地球观察者的角度来说的。如果我们换一个角度,比如说,从光子自己的视角来看待这段旅程,又会是…