napi常见用法:class对象绑定

napi常见用法:class对象绑定

HarmonyOS
2024-05-23 21:46:39
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
kaijunx

通过class对象绑定,可以在js中直接使用C++中定义实现的class,js中只用提供相关接口,即可调用。

下面提供一个案例介绍如何使用js侧新建C++对象,并使用C++对象的函数。

定义C++ 类

src/main/cpp/include/MyDemo.h

#ifndef NativeDemo_MyDemo_H 
#define NativeDemo_MyDemo_H 
#include <string> 
  
  
// 定义C++ 类 
class MyDemo { 
public: 
MyDemo(std::string name); 
MyDemo(); 
~MyDemo(); 
  
  
std::string name; 
  
  
int add(int a, int b); 
int sub(int a, int b); 
  
  
}; 
  
  
#endif //NativeDemo_MyDemo_H

实现C++ 类

src/main/cpp/src/MyDemo.cpp

#include "../include/MyDemo.h" 
  
  
// 实现C++ 类 
MyDemo::MyDemo(std::string name) { 
this->name = name; 
} 
  
  
MyDemo::MyDemo() {} 
  
  
MyDemo::~MyDemo() {} 
  
  
int MyDemo::add(int a, int b) { 
return a + b; 
}

定义JS接口,无需实现

注意:JS接口不是必须的,定义是为了ide能够正常提供代码提醒和校验功能。

src/main/cpp/types/libentry/index.d.ts

declare namespace testNapi { 
const add: (a: number, b: number) => number; 
const sub: (a: number, b: number) => number; 
const getString: (a: string) => string; 
// 定义js接口 
class MyDemo { 
constructor(name:string) 
name: string 
add(a: number, b: number): number 
sub(a: number, b: number): number 
} 
}   
export default testNapi;

napi绑定操作

src/main/cpp/hello.cpp

#include "napi/native_api.h" 
#include "include/MyDemo.h" 
#include <js_native_api.h> 
#include "hilog/log.h" 
#include <js_native_api_types.h> 
#include <string> 
  
  
#define LOG_DOMAIN 0x00CC 
#define LOG_TAG "ckTest" 
  
  
// js对象构造函数 
static napi_value JsConstructor(napi_env env, napi_callback_info info) { 
// 创建napi对象 
napi_value jDemo = nullptr; 
  
  
size_t argc = 1; 
napi_value args[1] = {0}; 
  
  
// 获取构造函数入参 
napi_get_cb_info(env, info, &argc, args, &jDemo, nullptr); 
  
  
// args[0] js传入的参数 
char name[50]; 
size_t result = 0; 
napi_get_value_string_utf8(env, args[0], name, sizeof(name) + 1, &result); 
  
  
// 创建C++对象 
MyDemo *cDemo = new MyDemo(name); 
OH_LOG_INFO(LOG_APP, "%{public}s", (cDemo->name).c_str()); 
  
  
// 设置js对象name属性 
napi_set_named_property(env, jDemo, "name", args[0]); 
  
  
// 绑定JS对象与C++对象 
napi_wrap( 
env, jDemo, cDemo, 
// 定义js对象回收时回调函数,用来销毁C++对象,防止内存泄漏 
[](napi_env env, void *finalize_data, void *finalize_hint) { 
MyDemo *cDemo = (MyDemo *)finalize_data; 
delete cDemo; 
cDemo = nullptr; 
}, 
nullptr, nullptr); 
return jDemo; 
} 
  
  
// js对象add函数 
static napi_value JsAdd(napi_env env, napi_callback_info info) { 
size_t argc = 2; 
napi_value args[2] = {nullptr}; 
napi_value jDemo = nullptr; 
napi_get_cb_info(env, info, &argc, args, &jDemo, nullptr); 
MyDemo *cDemo = nullptr; 
// 将js对象转为c对象 
napi_unwrap(env, jDemo, (void **)&cDemo); 
// 获取js传递的参数 
int value0; 
napi_get_value_int32(env, args[0], &value0); 
int value1; 
napi_get_value_int32(env, args[1], &value1); 
int cResult = cDemo->add(value0, value1); 
napi_value jResult; 
napi_create_int32(env, cResult, &jResult); 
return jResult; 
} 
  
  
// js对象sub函数 
static napi_value JsSub(napi_env env, napi_callback_info info) { 
size_t argc = 2; 
napi_value args[2] = {nullptr}; 
napi_value jDemo = nullptr; 
napi_get_cb_info(env, info, &argc, args, &jDemo, nullptr); 
MyDemo *cDemo = nullptr; 
// 将js对象转为c对象 
napi_unwrap(env, jDemo, (void **)&cDemo); 
// 获取js传递的参数 
int value0; 
napi_get_value_int32(env, args[0], &value0); 
int value1; 
napi_get_value_int32(env, args[1], &value1); 
int cResult = cDemo->sub(value0, value1); 
napi_value jResult; 
napi_create_int32(env, cResult, &jResult); 
return jResult; 
} 
static napi_value Init(napi_env env, napi_value exports) { 
  
  
// 定义模块需要对外暴露的方法 
napi_property_descriptor desc[] = { 
// {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}, 
// {"sub", nullptr, Sub, nullptr, nullptr, nullptr, napi_default, nullptr}, 
// {"getString", nullptr, GetString, nullptr, nullptr, nullptr, napi_default, nullptr} 
}; 
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 
  
  
// 通过napi_define_class建立JS类与C++侧的映射关系,然后将对应的对象挂载到export上 
napi_property_descriptor classProp[] = { 
{"add", nullptr, JsAdd, nullptr, nullptr, nullptr, napi_default, nullptr}, 
{"sub", nullptr, JsSub, nullptr, nullptr, nullptr, napi_default, nullptr}}; 
  
  
napi_value jDemo = nullptr; 
const char *jDemoName = "MyDemo"; 
// 建立JS构造函数与C++方法的关联,指定2个prop 
napi_define_class(env, jDemoName, sizeof(jDemoName), JsConstructor, nullptr, sizeof(classProp) / sizeof(classProp[0]), classProp, &jDemo); 
napi_set_named_property(env, exports, jDemoName, jDemo); 
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); 
}

JS调用测试

import hilog from '@ohos.hilog'; 
// 引入编译生成的库 
import testNapi from 'libentry.so' 
  
  
@Entry 
@Component 
struct Index { 
@State message: string = 'Hello World' 
  
  
build() { 
Row() { 
Column() { 
Text("获取对象") 
.fontSize(50) 
.fontWeight(FontWeight.Bold) 
.onClick(() => { 
//调用构造函数,获取对象 
let myDemo = new testNapi.MyDemo("zhangsan"); 
hilog.info(0x0000, 'ckTest', 'Test myDemo = %{public}s', JSON.stringify(myDemo)); 
hilog.isLoggable(0x0000, 'ckTest', hilog.LogLevel.INFO); 
// 调用c++ native函数 
//调用对象中成员函数 
hilog.info(0x0000, 'ckTest', 'Test NAPI 3 + 5 = %{public}d', myDemo.add(3, 5)); 
hilog.info(0x0000, 'ckTest', 'Test NAPI 2 - 1 = %{public}d', myDemo.sub(2, 1)); 
}) 
} 
.width('100%') 
} 
.height('100%') 
} 
}
分享
微博
QQ
微信
回复
2024-05-24 21:03:43
相关问题
NAPI中定义并注册Class
297浏览 • 1回复 待解决
ArkTS对象绑定的C++对象如何回收?
348浏览 • 1回复 待解决
求js 中 class类名动态绑定的问题?
5100浏览 • 1回复 待解决
getWindow().setBackground用法
3419浏览 • 1回复 待解决
InputMethodAbility用法是怎样的
6311浏览 • 1回复 待解决
关于measureTextSize的用法
300浏览 • 1回复 待解决
如何对常见密钥进行格式转换
199浏览 • 1回复 待解决
如何理解Intent类及其用法
5377浏览 • 4回复 已解决
高阶组件树视图基本用法
319浏览 • 1回复 待解决
class二次刷新渲染数组
286浏览 • 1回复 待解决
封装HTTP请求在ArkTS中常见
1627浏览 • 1回复 已解决
resource中string.json的用法
5334浏览 • 1回复 已解决
TiDB + Flink 结构常见的应用有哪几类?
1813浏览 • 1回复 待解决