HarmonyOS鸿蒙Next中如何将C++封装后的对象在ArkTS中传入
HarmonyOS鸿蒙Next中如何将C++封装后的对象在ArkTS中传入
c++ 类通过 napi_wrap 封装后,在ArkTS中调用该类的方法时,通过 napi_unwrap 解封装后,即可正常使用,但我目前想要实现两个类 A、B 封装后的互调,请问如何将对象传入并进行解析,如:
class A { }
class B {
public:
void doA(A* a);
}
主要是如何将传入的参数, 从 napi_value 转换为 object A
你是否想问如何实现ArkTS与C/C++的对象传递?
可以参考如下demo
ArkTS类对象传递至NAPI侧; NAPI获取对象属性并输出; NAPI调用对象方法。
// Animals类
class Animals {
name: string
age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
add(a: number, b: number): number {
return a + b;
}
}
// ArkTS传递对象中
Button("TestObject")
.onClick(() => {
let ani:Animals = new Animals('Bob',5)
testNapi.TestObject(ani)
})
// NAPI接受对象并处理
static napi_value TestObject(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);
napi_value name, age;
napi_get_named_property(env, args[0], "name", &name);
napi_get_named_property(env, args[0], "age", &age);
size_t itemLength;
napi_get_value_string_utf8(env, name, nullptr, 0, &itemLength);
char *str = new char[itemLength + 1];
napi_get_value_string_utf8(env, name, &str[0], itemLength + 1, &itemLength);
OH_LOG_INFO(LOG_APP, "name is %{public}s", str);
uint32_t num;
napi_get_value_uint32(env, age, &num);
OH_LOG_INFO(LOG_APP, "age is %{public}d", num);
napi_value add;
napi_get_named_property(env, args[0], "add", &add);
// 创建参数数组
napi_value arr[2];
napi_create_int32(env, 10, &arr[0]);
napi_create_int32(env, 5, &arr[1]);
napi_value result;
uint32_t res;
napi_call_function(env, args[0], add, 2, arr, &result);
napi_get_value_uint32(env, result, &res);
OH_LOG_INFO(LOG_APP, "res is %{public}d", res);
return nullptr;
}
ArkTS侧传递回调方法到NAPI侧;
NAPI创建napi_value
指针类型的对象作为参数传递到回调方法;
ArkTS调用回调方法获取NAPI侧传入的参数并做修改;
NAPI侧获取修改后的参数并输出。
static bool Napi_AddPropertyInt32(napi_env env, napi_value obj, const char *key, int32_t value) {
napi_value key_napi = nullptr;
napi_status status = napi_create_string_utf8(env, key, NAPI_AUTO_LENGTH, &key_napi);
napi_value value_napi = nullptr;
status = napi_create_int32(env, value, &value_napi);
status = napi_set_property(env, obj, key_napi, value_napi);
return true;
}
static napi_value CallbackToArkTs(napi_env env, napi_callback_info info) {
// 获取ArkTS参数
size_t argc = 1;
napi_value js_cb = nullptr;
napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr);
// native回调到ts层的object
napi_value argv = nullptr;
napi_create_object(env, &argv);
Napi_AddPropertyInt32(env, argv, "type", 1);
Napi_AddPropertyInt32(env, argv, "index", 2);
// native回调到ts层
napi_value result = nullptr;
napi_call_function(env, NULL, js_cb, 1, &argv, &result);
// 获取ts修改后的object
napi_value typeNumber = nullptr;
napi_get_named_property(env, result, "type", &typeNumber);
int32_t number;
napi_get_value_int32(env, typeNumber, &number);
OH_LOG_INFO(LOG_APP, "修改后type: %{public}d", number);
// 返回修改后的object
return result;
}
napi_serialize
、napi_deserialize
、napi_delete_serialization_data
用于将ArkTS对象转换为native数据、将native数据转为ArkTS对象、删除序列化数据等操作,参考:
napi_serialize、napi_deserialize、napi_delete_serialization_data
更多关于HarmonyOS鸿蒙Next中如何将C++封装后的对象在ArkTS中传入的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,若要将C++封装后的对象在ArkTS中传入,可以通过以下步骤实现:
-
使用NAPI接口:NAPI(Native API)是鸿蒙提供的一种机制,允许在ArkTS中调用C++代码。你需要通过NAPI将C++对象暴露给ArkTS。
-
创建C++类:首先在C++中定义并实现你的类,确保该类可以被NAPI封装。
-
封装对象:使用NAPI提供的函数将C++对象封装为一个可以在ArkTS中使用的对象。具体步骤包括:
- 使用
napi_define_class
定义ArkTS中的类。 - 使用
napi_wrap
将C++对象封装为ArkTS对象。
- 使用
-
暴露对象到ArkTS:通过
napi_set_named_property
或napi_define_properties
将封装后的对象暴露给ArkTS模块。 -
在ArkTS中使用:在ArkTS中导入该模块后,可以直接使用封装后的C++对象。
示例代码片段:
#include <napi.h>
class MyClass {
public:
MyClass() {}
void doSomething() {
// C++逻辑
}
};
Napi::Object Init(Napi::Env env, Napi::Object exports) {
Napi::Function func = DefineClass(env, "MyClass", {
InstanceMethod<&MyClass::doSomething>("doSomething")
});
exports.Set("MyClass", func);
return exports;
}
NODE_API_MODULE(addon, Init)
在ArkTS中使用:
import { MyClass } from './my_module';
let myObj = new MyClass();
myObj.doSomething();
在HarmonyOS鸿蒙Next中,将C++封装后的对象传入ArkTS,可以通过以下步骤实现:
- 创建Native接口:使用
napi
或NAPI
在C++中定义Native接口,将C++对象封装为napi_value
。 - 注册Native模块:在
CMakeLists.txt
中配置Native模块,并将其注册到ArkTS运行时。 - 在ArkTS中调用:通过
import
引入Native模块,调用封装好的接口,传入C++对象。
示例代码:
napi_value CreateObject(napi_env env, napi_callback_info info) {
// 创建并返回C++封装的对象
return napi_create_object(env);
}
import native from 'libnative.so';
let obj = native.createObject();
确保C++对象和ArkTS之间的数据类型兼容,并正确处理生命周期管理。